FDS or not to FDS

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: FDS or not to FDS

Post by tokumaru »

Regular NES ROMs probably reach wider audiences than FDS images. If you can do it without the FDS, and evidence indicates it's perfectly possible, you should do it.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: FDS or not to FDS

Post by rainwarrior »

Oziphantom wrote:is it going to annoy people that its on a FDS and there is no hardware support?
Both PowerPak and Everdrive simulate it quite well, IMO. Most emulators do too.

The trickiest thing to emulate, I think, is the modulation feature of its expansion audio, but as long as you don't use super high frequency modulation effects most emulators will do a pretty good job.

For those that have a real FDS, there are devices like the FDSStick and the older FDSLOADR that can simulate a disk drive very well. (The FDSStick is fantastic.)

Otherwise, if you want to do the "real" thing and put it on a disk, making and distributing actual disks might be a pain, and a lot of existing FDS drives are very temperamental and/or broken. This is really the only annoying aspect of it, to my mind, but it really only applies if it's a physical disk exclusive.
tokumaru wrote:Regular NES ROMs probably reach wider audiences than FDS images. If you can do it without the FDS, and evidence indicates it's perfectly possible, you should do it.
Possibly. I think the big sticking point there is that emulators don't come with the FDS BIOS ROM.
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: FDS or not to FDS

Post by AWJ »

Oziphantom wrote:@AWJ
Sprites will also be used for the fixed HUD on the side, of which 2 for player + 6 for Score = 8. So that basically pushes me into using chars for the pick-ups. On the C64 they are spites ;) as are the octopus platforms ;) HUD too ;) In my original idea having 64 sprites should make this easy silly me...

I though about keeping the HUD in chars and doing the shifts and plots to keep it stable allowing me to keep pick-ups and moving platforms in sprites, but as the moving platforms can't be done in sprites and have to be chars, it makes sense to me to switch the HUD to sprites and put the pick-ups into chars while I'm at it. As then their scrolling will be "for free"

Doing a split for the water is probably how I will end up doing it, but if possible it would be nice to get the chars plotting in so the water can slowly eat the char rather than having the fixed cut off where what is behind doesn't show through.

Doing the CHR-ROM flips means every single platform has to be on the same X offset, or at least you have the X offset going left and X offset going right, which means you can't really have platforms that move at different speeds, well you can, but they you are using silly amounts of ROM. Then you can't have fast platforms and slow conveyor platforms. There is probably a 24 or so levels of flipping that could be worked out to hold all the possible combinations a screen needs in the ROM, but they are what 4K a bank? 96K of CHR ROM for the chars??? Although doing it this way would mean I can store the HUD chars at the 8 Y scroll offsets, getting more sprites back for the pick-ups,moving platform caps etc but then I have to plot the HUD chars as I move up and down which would probably eat more time in VBlank then removing the pick-ups when collected. But some mappers have 1K granularity right? That might make it more practical... hmm
edit another thought, is I should be able to fit all the chars with shifts into 1 set ( Table being the NES name? ) to which if I go the IRQ split and negate the pixel perfect water, would drop the problem to Screen map transfers only.

Thank you for the input, if you have more, or I've missed the boat, please share ;)
Yeah, you really don't need either dynamic characters nor bank switching for the moving platforms. With 256 character definitions there's plenty of room for "left edge", "middle" and "right edge" at every pixel position.

Another problem with trying to do "pixel perfect water" is that graphics are only 2bpp on both the NES and the C64. On the C64 (IIRC) you have 3 shared colors over the entire screen and 1 unique color per 8x8 character, so I guess if you use only the 3 shared colors for the water it's no problem. But if you constrain yourself to the C64 color limits on the NES, your game is going to look pretty bland and colorless (especially if you're using BG characters for a bunch of things that were sprites on the C64)

How are you storing your levels on the C64? Do you have the entire level in RAM as a giant screen map and just memcpy whatever part of it is visible into VRAM every frame? Since the moving platforms and pickups are sprites, I guess they're stored and updated totally separately from the main level data?

Also, on the C64 I guess you're using one sprite for the player, two for the score, and the rest for pickups and moving platforms? Do you just design the levels so there's never more than 5 sprites worth of pickups and platforms visible at a time, or are you doing sprite multiplexing?
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: FDS or not to FDS

Post by Oziphantom »

tepples wrote:I'm not sure what "animating and moving water" would take. But assuming the "2 animated tiles" can update at 30 fps, the rest is 6 transactions copying 92 bytes:
  • 32-byte copy: Vertical scroll seam at 8 px/frame (2 screen heights per second)
  • 8-byte copy: Attributes for said seam
  • 3 x 12-byte copy: 3 moving platforms
  • 16-byte copy: 1 of 2 animated tiles, alternating
The fastest variant of the Popslide blitter uses 3 bytes and an estimated 50 cycles per copy transaction, plus 1 byte and 8 cycles per copied byte. Thus it'd take 92+3*6 = 110 bytes of page $01 and 8*92+50*6 = 1036 cycles to update VRAM. Add 526 cycles to copy the sprite list to OAM, and you're still well within 2270 cycles of NTSC vblank.

A raster split with highly variable vertical position is doable but tricky on a discrete mapper, particularly if you need the DMC free for sampled drums or bass. Without an interval timer to interrupt the CPU at the split point, you end up estimating the worst-case execution time in scanlines of every subroutine, running those that fit before the wait for sprite 0, and running everything else afterward.

Verdict: It can be done without FDS.
If I skip scaling the world down and let it be full screen, which will look wrong, but might need to be done. This also requires that I put a fixed hud up the top, which I might just have to make be the timer, and leave the rest for the intermission screen. Then it gets possible to store all the chars in a single 256 bank, as now each "block" is 8x8 again.

The original game is narrow, i.e. it looks taller than it is wide. This is achieved on the Wii-U(16:9) by the side border. The C64 is 16:10 so I added an extra column to the side border and it basically looks about right. The NES being 4:3 means its going to look like Rainbow Islands, wide and short.

I was also thinking I might be able to get away with using colour emphasis for the water ;)
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: FDS or not to FDS

Post by Oziphantom »

AWJ wrote:
Oziphantom wrote:@AWJ
Sprites will also be used for the fixed HUD on the side, of which 2 for player + 6 for Score = 8. So that basically pushes me into using chars for the pick-ups. On the C64 they are spites ;) as are the octopus platforms ;) HUD too ;) In my original idea having 64 sprites should make this easy silly me...

I though about keeping the HUD in chars and doing the shifts and plots to keep it stable allowing me to keep pick-ups and moving platforms in sprites, but as the moving platforms can't be done in sprites and have to be chars, it makes sense to me to switch the HUD to sprites and put the pick-ups into chars while I'm at it. As then their scrolling will be "for free"

Doing a split for the water is probably how I will end up doing it, but if possible it would be nice to get the chars plotting in so the water can slowly eat the char rather than having the fixed cut off where what is behind doesn't show through.

Doing the CHR-ROM flips means every single platform has to be on the same X offset, or at least you have the X offset going left and X offset going right, which means you can't really have platforms that move at different speeds, well you can, but they you are using silly amounts of ROM. Then you can't have fast platforms and slow conveyor platforms. There is probably a 24 or so levels of flipping that could be worked out to hold all the possible combinations a screen needs in the ROM, but they are what 4K a bank? 96K of CHR ROM for the chars??? Although doing it this way would mean I can store the HUD chars at the 8 Y scroll offsets, getting more sprites back for the pick-ups,moving platform caps etc but then I have to plot the HUD chars as I move up and down which would probably eat more time in VBlank then removing the pick-ups when collected. But some mappers have 1K granularity right? That might make it more practical... hmm
edit another thought, is I should be able to fit all the chars with shifts into 1 set ( Table being the NES name? ) to which if I go the IRQ split and negate the pixel perfect water, would drop the problem to Screen map transfers only.

Thank you for the input, if you have more, or I've missed the boat, please share ;)
Yeah, you really don't need either dynamic characters nor bank switching for the moving platforms. With 256 character definitions there's plenty of room for "left edge", "middle" and "right edge" at every pixel position.

Another problem with trying to do "pixel perfect water" is that graphics are only 2bpp on both the NES and the C64. On the C64 (IIRC) you have 3 shared colors over the entire screen and 1 unique color per 8x8 character, so I guess if you use only the 3 shared colors for the water it's no problem. But if you constrain yourself to the C64 color limits on the NES, your game is going to look pretty bland and colorless (especially if you're using BG characters for a bunch of things that were sprites on the C64)

How are you storing your levels on the C64? Do you have the entire level in RAM as a giant screen map and just memcpy whatever part of it is visible into VRAM every frame? Since the moving platforms and pickups are sprites, I guess they're stored and updated totally separately from the main level data?

Also, on the C64 I guess you're using one sprite for the player, two for the score, and the rest for pickups and moving platforms? Do you just design the levels so there's never more than 5 sprites worth of pickups and platforms visible at a time, or are you doing sprite multiplexing?
Levels are stored
deltas .......
type .......
startx ......
endx .......
which I then walk through and build a large tile map in RAM. As shifting the screen and plotting is basically as fast as just blanket coping it all again from RAM. This way the Water if it is there just gets drawn, without me doing a char shift, then plotting the new row, then seeing if I need to plot more water. Also it keeps the random background tiles consistent across all scrolls. Having them change as you jump back up might be noticeable, so I might need to keep a buffer of them for the near scroll, i.e when you at you apex and fall on a platform you will dip below the top char then jump again, potentially rapidly, so having it switch so fast might be jarring.

However to shift CRAM which I only need to do on platforms, I walk though the data set and track where I am and hence were platforms are on the screen to do the CRAM shift, while doing this walk I'm able to add and remove "sprite" entities from the active list.

The sprites are split rather than plexed. The Player and Pickups are 2 sprites, 1 hires, 1 multi, the moving platforms are hires. The HUD is 2 sprites as well. so this give per line
2 player 0-4 platform or pickup 2 HUD.

It is not a very colourful game on the original, its aiming to be NES style. I use ECBM on the C64, so all the tiles are hires, but I have 4 background colours. this gives me the ability to have 1 of 4 colours paired with 1 of 16 colours in an 8x8 block, then I have 2 fixed sprite colours and then I can choose from the full 16 for the sprites other colour and the other sprite can have any of 16 as well. Where each "pickup" has 2 fixed and 2 of the 16.
image1.bmp
image1.bmp (51.12 KiB) Viewed 4116 times
image2.bmp
image2.bmp (51.12 KiB) Viewed 4116 times
image3.bmp
image3.bmp (51.12 KiB) Viewed 4116 times
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: FDS or not to FDS

Post by Pokun »

Oziphantom wrote: I was also thinking I might be able to get away with using colour emphasis for the water ;)
Colour emphasis might not be so strong on real TVs as they look in many emulators. On my TV it's quite weak for some reason.
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: FDS or not to FDS

Post by AWJ »

Out of curiosity, what frame rate does your game run at on the C64 and what is the player's maximum vertical velocity? (i.e. how often do you have to replot the entire playfield?)

Doing the HUD on the side of the screen in sprites is fine. You'll just have to scale the playfield down to 24 columns, meaning all your platforms will be 3/4 the width they are on the C64.

After looking at your C64 screenshots, I'm even more convinced that you're better off using sprites for the pickups. That way the pickups can overlap the background stars, and they aren't competing for palettes with the platforms and stars and water. Assuming you never have more than one pickup on the same horizontal line, the only time you'll exceed the 8 sprite limit is when the player, a pickup, and a row of the HUD using 5 or more sprites are all on the same line. You can minimize the frequency of that by using squished letters to fit "STAGE" in 4 sprites (use a 6-pixel-pitch font for the entire HUD so it doesn't stand out like a sore thumb) and tweaking your scrolling algorithm so that the player is usually below the score and above the timer. Finally, alternate your OAM order each frame between HUD->player->pickups and HUD->pickups->player so that sprites flicker rather than disappear altogether on the occasion when too many do overlap.

Here's your sprite pattern budget for the HUD:
  • HI
  • SCORE and STAGE squished so each word fits in 4 sprites
  • Lives symbol
  • 6-pixel-wide digits from 0 to 9
  • 6-pixel-wide digits squeezed to the left with half a colon on the right
  • 6-pixel-wide digits squeezed to the right with half a colon on the left
The last two are for the timer, so you can display 5 digits and 2 colons with 5 sprites.

I'd suggest storing the levels as an array of indexes into a lookup table of predrawn 24x2 character rows (platforms, stars, color attributes and collision maps all precalculated and stored in ROM) If you try to copy your C64 approach on the NES, even aside from the RAM requirements you're going to have a big pain with your attribute tables (C64 color RAM equivalent)--remember that color regions are 2x2 characters on the NES, and also that four of those 2x2 character regions are packed into one byte. Also, you don't want stars on the same line as a moving platform, or they're going to get erased as the platform moves. You can make some of your predrawn rows have the platform in their upper half and some have it in the lower half to make it less obvious that every two rows are one predrawn unit.

Along with VBlank constraints, the fact that video memory is sequential-access rather than random-access on the NES has a huge effect on how you do things. You usually end up having to shadow your attribute tables in work RAM so that you don't have to read back video memory whenever you plot something smaller than 4x4 tiles. Modifying characters in place in CHR RAM (e.g. sliding or compositing) is very cycle-expensive and rarely done--almost all games with cycling background animations use CHR ROM and bank flipping.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: FDS or not to FDS

Post by Oziphantom »

50/60fps depending on which model you use and the y velocity is clipped to 15ppf which it will sustain for quite a few frames, I've not measured it, but it does hold it for more than 4 ;) If you want to try it out there is an old version with the "easy to test" physics here http://www.lemon64.com/forum/viewtopic. ... c&start=45 probably safest to run the emulator in PAL mode.

Scaling it down to 24 chars wide then puts everything on a 6x6 grid, the issue there is storing all the tiles in ROM blows up. I have to stick to an 8x8 grid to be able to keep all the tiles I need in one ROM bank, probably, maybe with careful choosing and limiting what "row" this or that can be on, one might get away with it.
I was thinking of caching the Bubbles for the lines that have the moving platforms, and plotting them back as it moved.
The player has a max height on the screen, so I could rearrange the HUD such that the Level and number + lives where in the Player Range, then the timer was up the top. Flicker should be avoided at all costs ;) only if strictly necessary. But I feel that the 8x8 char is the path I must take to which the side HUD goes away.

If one has RAM, for the cycling chars, you can keep a copy in CPU land, then rol shift etc, then you write it to CHR-RAM which looks like it would just be a
Set ADDR
Write byte x 16
The trick being if one is drowning in RAM, one can use in place speed code ;)

Code: Select all

transferChar
lda #<addr
sta reg
lda #>addr
sta reg
lda #A
sta reg
lda #B
sta reg
lda #C
sta reg
...

Then when you roll you do
asl transferChar+10
rol transferChar+10
asl transferChar+14
rol transferChar+14
Storing 2x24 blocks that it marches though sounds like a great idea, thanks.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: FDS or not to FDS

Post by tepples »

Not being from mainland Europe, I'm unfamiliar with Commodore 64 demoscene jargon. Does "speed code" mean unrolled loops?
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: FDS or not to FDS

Post by AWJ »

Oziphantom wrote:Scaling it down to 24 chars wide then puts everything on a 6x6 grid
Why? Is it absolutely necessary and non-negotiable that the playfield must be 32 units wide?
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: FDS or not to FDS

Post by Oziphantom »

Mostly. It more or less refers to dynamically generated code use to speed up things. Its normal use case is for things that one wouldn't hand write code for but you make a generator to handle it. This can involve making rolled out loops, or just removing conditional branches or both. It can also include self mod and/or ZP relocation to improve self mod speed. "normal" uses for it are IFLI screens, 2x2 chunky mode plotters, tunnels, Multiplexors etc
Basically if one throws normal sensibilities out the window in the name of pure speed, then its "speed code" rather than just "daft" :D
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: FDS or not to FDS

Post by Oziphantom »

AWJ wrote:
Oziphantom wrote:Scaling it down to 24 chars wide then puts everything on a 6x6 grid
Why? Is it absolutely necessary and non-negotiable that the playfield must be 32 units wide?
Basically the distance and ratios of the game are basically for all intents the game.
If you make the squid narrower than the rest of the world it will look squished, if you keep it in the same proportions then the the squid needs to constrained to compensate.
And all the levels will be designed to be 31 centric :D

It might work, I would have to make a test and see if the feel is still there, my gut from balancing the C64 movements, is it won't be.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: FDS or not to FDS

Post by tepples »

After what happened to AM2R, you might need to redesign the squid character anyway.
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: FDS or not to FDS

Post by AWJ »

Oziphantom wrote:
AWJ wrote:
Oziphantom wrote:Scaling it down to 24 chars wide then puts everything on a 6x6 grid
Why? Is it absolutely necessary and non-negotiable that the playfield must be 32 units wide?
Basically the distance and ratios of the game are basically for all intents the game.
If you make the squid narrower than the rest of the world it will look squished, if you keep it in the same proportions then the the squid needs to constrained to compensate.
And all the levels will be designed to be 31 centric :D

It might work, I would have to make a test and see if the feel is still there, my gut from balancing the C64 movements, is it won't be.
Okay, after sketching things out in a tile editor I think a 32-tile wide playfield using 24 hardware tiles is completely doable, given the simplicity of the game's graphics.

What you really want is a 6x8 grid rather than 6x6, because the vertical resolution is the same on the NES as on the C64 (actually the NES has a little more than the C64). So every 3 hardware tiles are going to contain 4 game tiles. Given that there's only one platform per row, we need 9 patterns for each type of non-moving platform: 3 alignments each for "left edge", "middle", and "right edge". For the moving platform we need 20 tiles: 6 tiles for "middle" and 7 tiles each for "left edge" and "right edge". Take a look at this mockup and see if you agree:
6x8mockup.png
6x8mockup.png (5.73 KiB) Viewed 4037 times
To move the moving platforms, you're going to want a lookup table in ROM with the sequence of tiles to draw depending on the platform's position % 8 and its length. Also, I highly recommend making the moving platforms and the background bubbles use the same palette so that you don't have to mess with the attribute table as the platforms move.

So here's your background pattern budget:
  • Blank blue tile
  • Blank black tile for HUD
  • 9 tiles for normal platforms
  • 9 tiles for ice platforms
  • 9 tiles for conveyor belts
  • 20 tiles for moving platforms
  • However many for water and bubbles
That's easily less than 64 tiles.

Now, with the conveyor belts using 9 tiles (per direction!) you're definitely going to want to use CHR ROM bank flipping to move them rather than plotting to CHR RAM. Not a big deal, every common mapper that supports raster IRQs also supports 1KB CHR ROM granularity.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: FDS or not to FDS

Post by Oziphantom »

Sounds a plan.

Any good tile editors that work in Win10. TM has tiny tiny text and the hit box of the "tool" is off, making it nigh on impossible to use.

Also the NES pixel ratio is about ~1:1 ? PAL and NTSC?
Post Reply