SNES Splatoon (How do I shot HiROM?)

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

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Drew Sebastino »

Oh yeah, how do you multiply on the SNES? I looked at the SNES hardware register page on superfamicom.org and it lists the multiplicand and multiplier registers for the CPU, but it doesn't seem to for the 8x16 multiplication in the PPU for mode 7. However, it does list the registers that hold the product. Obviously, we're not dealing with Mode 7 here so it should be safe.
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by 93143 »

The part that talks about the result registers tells you what the inputs are. They're just part of the Mode 7 matrix.

This is a neat idea, though. Good thing it's not me conceptualizing it - I'd have insisted on doing a full 3D version with the Super FX2 and software texture re-rendering or some nonsense... with explicit XBAND support, of course... I haven't yet learned that there's a difference between what a SNES could do and what a SNES should do...
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Drew Sebastino »

93143 wrote:The part that talks about the result registers tells you what the inputs are. They're just part of the Mode 7 matrix.
Wow, I'm an idiot...
Registers 211b through 2120 are 16 bits wide.
0x211B is also used as the 16-bit multiplicand for registers 0x2134-6 (write twice)
0x211C is also used as the 8-bit multiplier for registers 0x2134-6
What does it mean by "write twice" though? Is it just that it's two 8 bit writes, or one 16 bit write?

Anyway, I think I figured out how to calculate the vertical offset: You take the YPosition, divide it by 8 by bit shifting, multiply this number by the amount of pixels in the buffer horizontally times the amount of data per tile (pre calculated obviously) store this, load YPosition again, "and" this to where only the first 3 bits are left, multiply this number times the amount of data per 8 pixels (2 for 2 bytes) and then add the result of the previous thing to this for the final result. I'll probably code this tomorrow and try and do some other stuff to it also.
93143 wrote:This is a neat idea, though.
Just thinking, another thing that made me thing about it is how the maps are mostly 2D but with elevation differences. I wonder how well you could port the maps in this game to Doom... :lol:
93143 wrote: Good thing it's not me conceptualizing it - I'd have insisted on doing a full 3D version with the Super FX2 and software texture re-rendering or some nonsense... with explicit XBAND support, of course... I haven't yet learned that there's a difference between what a SNES could do and what a SNES should do...
Are you regretting working with the Super FX? Although something like XBAND is obviously out of the question, making a local cable for hooking multiple SNES's together would be awesome. I was actually thinking about this in the old discussion about how a 2 player F-Zero wouldn't be (easily) possible because of only having one tilemap.

Wait... SNES Doom could be 2 player!? https://www.youtube.com/watch?v=-P3JGxBNUyM I didn't think any game actually worked around the XBAND. It's not like there's a game built around the Game Genie anyway.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by koitsu »

Espozo wrote:
Registers 211b through 2120 are 16 bits wide.
0x211B is also used as the 16-bit multiplicand for registers 0x2134-6 (write twice)
0x211C is also used as the 8-bit multiplier for registers 0x2134-6
What does it mean by "write twice" though? Is it just that it's two 8 bit writes, or one 16 bit write?
Talking purely about mode 7 crap:

It means two 8-bit writes, in the order of low byte followed by high byte of whatever 16-bit multiplicand value you have. The 16-bit value is signed, so the MSB of the 16-bit value defines signage.

A native 16-bit write to $211B would write to both registers $211B and $211C, which isn't what you want.

Proper order of operation:

1. Write 8-bit value (lower byte of multiplicand) to $211b
2. Write 8-bit value (upper byte of multiplicand) to $211b
3. Write 8-bit value (multiplier) to $211c
4. Read $2134, $2135, $2136 for results

I've never done mode 7 stuff, and these registers are actually described more thoroughly in the official documentation, including mentioning something about decimal placement.

If what you're looking for is literal/absolute unsigned multiplication or division, then those can be done through different registers. For 8-bit multiplication (with a 16-bit result):

1. Write $4202 (multiplicand) (8-bit)
2. Write $4203 (multiplier) (8-bit)
3. Wait 8 CPU cycles
4. Read $4216 (result or "product") (16-bit)

For division:

1. Write $4204 (dividend) (16-bit)
2. Write $4206 (divisor) (8-bit)
3. Wait 16 CPU cycles
4. Read $4214 (quotient) (16-bit)
5. Read $4216 (remainder) (16-bit)

The order in which you write to these registers matters.

"Wait N CPU cycles" means you won't have a valid result (in $4216/4217) until N number of CPU cycles has passed. You can do other things in the meantime (i.e. you don't need to do 8 or 16 cycles worth of NOPs unless you really want to).
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by 93143 »

Espozo wrote:Are you regretting working with the Super FX?
No, no. It's just that in this case, judging by how Doom turned out, I imagine it'd probably be better to go with a demake rather than trying for a direct port. In the case of the shmup I'm porting, based on my calculations I think I can pretty much preserve the gameplay and (to an extent) the graphical look and feel without having to redesign it to fit on the platform. Splatoon is a different matter.

Why add a coprocessor (thus "cheating") and all the programming headaches of a 3D Super FX game in order to produce an end product that looks and plays worse than a 2D version that would only have needed the base hardware? Not to mention that while a 2D version would be its own thing, a 3D version would just be a bad version of the Wii U game.

As I said, I'm speaking against my instincts here...
koitsu wrote:"Wait N CPU cycles" means you won't have a valid result (in $4216/4217) until N number of CPU cycles has passed.
If I recall correctly, the ALU multiplier does give a valid result early if the numbers being multiplied are small. Taz-Mania relies on this behaviour, and I believe higan emulates it correctly. As far as I know, no other emulator even bothers with the delay.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Drew Sebastino »

Wait, I'm an idiot, instead of leaving empty space at the graphic for the splat at the bottom and the top, I could just still draw the splat tile by tile, but I'd have special code for each tile height. It would go through the first tile height loop for one whole row, then it would go to the second for more than likely multiply rows and this would undoubtedly be 8 pixels tall, and then it would go to the last loop. Although there'd be slightly more preparation at the beginning for this, it would probably still save time overall and a little memory too. I'm working on it now.
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by 93143 »

Espozo wrote:I was actually thinking about this in the old discussion about how a 2 player F-Zero wouldn't be (easily) possible because of only having one tilemap.
You know, even F-Zero X and GX don't have multiplayer GPs like Mario Kart. It's always head-to-head with maybe a couple of CPU opponents. And X provides a precedent for streamlining the graphics in multiplayer modes. In that context, it seems less unreasonable to use double-buffered quarter-maps (possibly with reduced texture resolution to help ensure that the edges of a quarter-map are always out of sight) and devote 4 KB of DMA per frame to tilemap updates; there should be enough room for software-scaled sprites at a reasonable frame rate if there can only ever be 6 of them.

And I'm sure the SA-1 in an F-Zero SX cart could spare the ~6% of a frame it would take to build a half-dual-quarter-map for both players with repeated ROM-to-BWRAM DMA transfers, so it's ready for an easy one-shot DMA to VRAM during VBlank. You wouldn't need to waste VBlank time on Mode 7 HDMA tables for non-flat courses either, since unlike the Super FX (which either hogs its memory or can't use it at all) the SA-1 can share memory with the S-CPU, so if you build the tables in BWRAM there's no need to move them.

...see, that's how I normally think about SNES development (and I've barely scratched the surface of what I'd want to do with that game). I'm apparently a big fan of enhancement chips. I know lots of people consider it cheating, but I just don't feel it...
Attachments
2pmap_fzero_halfupdate.png
2pmap_fzero_halfupdate.png (520 Bytes) Viewed 3012 times
Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Sik »

There's a big difference between the kind of chips that were released at a time and a coprocessor based on modern hardware.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Drew Sebastino »

93143 wrote:You know, even F-Zero X and GX don't have multiplayer GPs like Mario Kart. It's always head-to-head with maybe a couple of CPU opponents. And X provides a precedent for streamlining the graphics in multiplayer modes. In that context, it seems less unreasonable to use double-buffered quarter-maps (possibly with reduced texture resolution to help ensure that the edges of a quarter-map are always out of sight) and devote 4 KB of DMA per frame to tilemap updates; there should be enough room for software-scaled sprites at a reasonable frame rate if there can only ever be 6 of them.
I know. We went over this, it's just at the time I didn't know. Anyway, I'm not interested in doing that, at the moment anyway.
93143 wrote:I know lots of people consider it cheating, but I just don't feel it...
Well, I mean, I wouldn't compare a game using software rendering vs. the Super FX... It's its own category.
Sik wrote:There's a big difference between the kind of chips that were released at a time and a coprocessor based on modern hardware.
Well, this is an entirely different category.

Anyway, about having the code for each tile height, I think I'll have the code for an 5 pixel height and then an 8 pixel height and then a 3 pixel height grouped together because it's faster, but I'm also lazy... :lol: The problem with this is though that it will always assume the splat is always at least 16 pixels tall, but I could always make it to where it skips the middle 8 pixel loop if it detects it's not big enough. I have it to where it skips this thing altogether and only goes to an 8 pixel loop if it's in exactly the right position, and by the nature of how this is, it works with 8 pixel high splats. I'll work on it again when I get home. In programming this, there's a lot to keep track of... (To me anyway.)
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by 93143 »

I'm sorry; I'm not intending to drag your thread off topic. I had just realized that with an SA-1, the map preparation actually seems quite tractable. And since you had mentioned it, and I had been generating (largely useless) noise over my tendency to want to use special chips with everything...

I might be interested in doing it. But probably not until after my current project, which is going to take a while...

I've posted my realization to the F-Zero 2-player thread, where it belongs.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Drew Sebastino »

It's fine. Most of the time, I derail my own topics anyway... :lol:

Anyway, what I said earlier about having the unrolled loop thing, (That's what an unrolled loop is, isn't it?) that's definitely the best option. I forgot how drawing four pixels at the top of a tile and drawing four at the bottom aren't exactly the same thing...

Also, I have the graphics format down for how I want the splats. it's going to alternate between a word that's a mask and a word that's the actual pattern, like I always thought I would. However, the main thing is I'll have it to where when the tile's completed, instead of going to the one on the right until the end of the row, it'll go all the way down and then over one. The reason for this is that regardless of vertical position of the splat, every line down is incremented by the same amount of data, which isn't the case for if it were the normal way because of tile boundaries. Luckily, I have no homework or tests so I can work on this again. I did not expect this to be even remotely as difficult as it is...

Also, are you squidding (sorry... :lol: ) me Nintendo?

Image

There are people in territories outside of Japan that play this game... Why aren't we allowed to have cheap gummies and crappy plastic watches and picture books mangas and admittedly cool plushies and t-shirts? :(
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Drew Sebastino »

Here's the rendering code for a splat that's been shifted down 3 pixels. (If the splat is partially off the screen vertically, it may skip the first tile row code and jump to the second or third set. This would be coded elsewhere.) Holy crap... I didn't expect it to be even a fraction as difficult to make as this, and the worst part is that I have to make this six more times... (The one for if the tile is directly in the right spot won't be nearly as difficult) I know this is a giant waste of memory, but frankly, I'm going to be more worried about my sanity in copying this several times... In the jump table for selecting what code to jump to because of the different vertical heights, I'll have all of them point to this, and if it works, I'll copy it. I need to fix the preparation code for this now. Anyway...

Code: Select all

start_draw_offset_3_splat:
  ldx SplatBufferPosition
  cpx EndOfBuffer
  bcs draw_offset_3_splat_done
  ldy SplatGraphicOffset
  lda SplatGraphicOffset
  clc
  adc #$0014
  sta SplatGraphicOffset

draw_offset_3_splat_first_rows:
  lda Buffer+6,x
  and #$0000,y
  ora #$0002,y
  sta Buffer+6,x

  lda Buffer+8,x
  and #$0004,y
  ora #$0006,y
  sta Buffer+8,x

  lda Buffer+10,x
  and #$0008,y
  ora #$000A,y
  sta Buffer+10,x

  lda Buffer+12,x
  and #$000C,y
  ora #$000E,y
  sta Buffer+12,x

  lda Buffer+14,x
  and #$0010,y
  ora #$0012,y
  sta Buffer+14,x

  inc TilesDrawnHorizontally
  cmp SplatTileWidth
  bcs start_offset_3_splat_middle_rows
  txa
  clc
  adc #$0010
  tax
  tya
  clc
  adc SplatDataHeight
  tay
  bra draw_offset_3_splat_first_rows

;======================================================================

start_draw_offset_3_splat_middle_rows:
  ldx SplatBufferPosition
  stz TilesDrawnHorizontally
  txa
  clc
  adc DataPerRowInBuffer
  tax
  ldy SplatGraphicOffset

draw_offset_3_splat_middle_rows:
  lda Buffer,x
  and #$0000,y
  ora #$0002,y
  sta Buffer,x

  lda Buffer+2,x
  and #$0004,y
  ora #$0006,y
  sta Buffer+2,x

  lda Buffer+4,x
  and #$0008,y
  ora #$000A,y
  sta Buffer+4,x

  lda Buffer+6,x
  and #$000C,y
  ora #$000E,y
  sta Buffer+6,x

  lda Buffer+8,x
  and #$0010,y
  ora #$0012,y
  sta Buffer+8,x

  lda Buffer+10,x
  and #$0014,y
  ora #$0016,y
  sta Buffer+10,x

  lda Buffer+12,x
  and #$0018,y
  ora #$001A,y
  sta Buffer+12,x

  lda Buffer+14,x
  and #$001C,y
  ora #$001E,y
  sta Buffer+14,x

  lda FullTilesDrawnVertically
  cmp FullTileSplatHeight
  bcs start_draw_offset_3_splat_last_rows
  inc TilesDrawnHorizontally
  cmp SplatTileWidth
  bcs offset_3_splat_next_row
  txa
  clc
  adc #$0010
  tax
  tya
  clc
  adc SplatDataHeight
  tay
  bra draw_offset_3_splat_middle_rows

offset_3_splat_next_row:
  cpx EndOfBuffer
  bcs draw_offset_3_splat_done
  inc FullTilesDrawnVertically
  inc TilesDrawnHorizontally
  txa
  clc
  adc DataPerRowInBuffer
  tax
  lda SplatGraphicOffset
  clc
  adc #$0020
  sta SplatGraphicOffset
  tay
  bra draw_offset_3_splat_middle_rows

;======================================================================

start_draw_offset_3_splat_last_rows:
  ldx SplatBufferPosition
  cpx EndOfBuffer
  bcs draw_offset_3_splat_done
  stz TilesDrawnHorizontally
  txa
  clc
  adc DataPerRowInBuffer
  tax
  ldy SplatGraphicOffset

draw_offset_3_splat_last_rows:
  lda Buffer,x
  and #$0000,y
  ora #$0002,y
  sta Buffer,x

  lda Buffer+2,x
  and #$0004,y
  ora #$0006,y
  sta Buffer+2,x

  lda Buffer+4,x
  and #$0008,y
  ora #$000A,y
  sta Buffer+4,x

  inc TilesDrawnHorizontally
  cmp SplatTileWidth
  bcs draw_offset_3_splat_done
  txa
  clc
  adc #$0010
  tax
  tya
  clc
  adc SplatDataHeight
  tay
  bra draw_offset_3_splat_last_rows
I hope it works... :lol:
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by psycopathicteen »

Address don't have a #.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Drew Sebastino »

I know. Where did I get that wrong?

Also, you actually read it?
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES Splatoon (Not Even A Demo Yet Though...)

Post by Drew Sebastino »

I think this should be the top, "preparation" part. It's got initialization stuff I still need to do, but it's mostly done if there aren't any problems I find with it. I still need to code where it says what tiles need to be uploaded, but I'll try and upload the tiles from a fixed position and if it works correctly, I'll implement it then. I also need to implement the splat being only partially on the buffer, but I have no clue how I want to do that. Oh yeah, and collision detection. Some tiles would be don't draw at all, and then some would be draw with an extra mask for diagonal walls and stuff like that. If I ever get this far, I kind of wonder how I'll handle collision detection with the player and the ink. I'll probably just check one pixel in the middle of them and see what color it is. Anyway...

Code: Select all

  lda SplatRequestTable+YPosition,x
  and #$0000000000000111
  asl
  bne continue_calculating_vertical_offset
  sta SplatSubTileYPosition

continue_calculating_vertical_offset:
  lda SplatRequestTable+YPosition,x
  ror
  ror
  ror
  sep #$20	;A=8
  sta $4202
  lda DataPerRowInBuffer
  sta $4203	;Apparently, there's some sort of waiting time for this?

  lda SplatRequestTable+Height,x
  sta FullTileSplatHeight
  asl
  asl
  asl
  asl
  asl
  sta DataSplatHeight
  lda SplatRequestTable+Width,x
  sta TileSplatWidth

  rep #$30	;A=16, X/Y=16
  lda $4216
  sta SplatBufferPosition

;======================================================================

  lda SplatRequestTable+XPosition,x
  ror
  ror
  and #%0011111111111111
  clc
  adc SplatBufferPosition
  sta SplatBufferPosition

  lda SplatRequestTable+XPosition,x
  and #%0000000000000111
  bne continue_calculating_x_offset
  inc TileSplatWidth
  lda SplatRequestTable+XPosition,x
  and #%0000000000000111

continue_calculating_x_offset:
  
  clc
  adc SplatRequestTable+GraphicOffset,x
  sta SplatGraphicOffset

  lda SplatSubTileYPosition
  asl
  tax
  jsr (VariableYOffsetCodeJumpTable,x)
...I just noticed how the Splatoon candy says "ikasu", just like on the Batman squid snacks... Well, at least it makes sense here. :lol:
Post Reply