WF FPGA Ideas: Difference between revisions

From F256 Foenix
Jump to navigationJump to search
(Created page with "== Global settings == CRT emulation, only for low resolution layers. 640x480 for 4:3 output, or 960x540 for 16:9 output, if bandwidth can run it. Non-integer pixel aspect flags, again only for low res layers. Match 320x200 and 256x200 non-square aspects blended on a 480p/540p base output. Keep it at 60Hz Select 50 or 60 Hz in any resolution. Ditch 70Hz, as nothing syncs to that in the PC space for compatibility. 50Hz is much lower priority, but can be done by extendin...")
 
No edit summary
Line 9: Line 9:


== Palettes ==
== Palettes ==
Reduce from 24-bit to 16-bit, better suited to 65816, and makes a lot of things simpler.
Reduce from 24-bit to 16-bit, better suited to 65816, and makes a lot of addressing simpler.


5-5-5-1 masked, or 4-4-4-4 RGBA? Leaning towards the latter. Have a FPGA block which separates & combines 4 values into 1, all R/W registers, avoid all the shifting. Using transparency 0=opaque, 15=fully transparent is probably easier.
5-5-5-1 masked, or 4-4-4-4 RGBA? Leaning towards the latter. Using transparency 0=opaque, 15=fully transparent is probably easier.


Palettes are always 4-4-4-4, but direct color 5-5-5-1 or 4-4-4-4 can be used for bitmap layers?
Have a FPGA block which separates & combines 4 values into 1, all R/W registers, avoid all the shifting. Include signed clamping when converting to the single RGB word.
 
'''Rougher ideas'''
 
Palettes are always 4-4-4-4, but direct color 5-5-5-1 or 4-4-4-4 can be used for bitmap layers? Probably best to keep it the same, but given clear displays today, the 5-5-5 would look better for full-color backgrounds.


== Layers ==
== Layers ==
Line 38: Line 42:
Individual layers, sprites, can have a transparency override, ignoring the palette value. If they don't, transparency from the palette per color can still be obeyed.
Individual layers, sprites, can have a transparency override, ignoring the palette value. If they don't, transparency from the palette per color can still be obeyed.


== Bit depth ==
'''TODO'''
 
Buffering sprites with no-overdraw is harder, probably needs its own linebuffer & alpha line buffer. Both the alpha and opaque layers need to track their own layer depth when merging together, as maybe only the alpha is visible but not the further back opaque sprite.
 
== Indexed Bit Depth ==
Currently, everything is 8bpp, which is high bandwidth, and more work to create artwork.
Currently, everything is 8bpp, which is high bandwidth, and more work to create artwork.



Revision as of 18:16, 25 December 2025

Global settings

CRT emulation, only for low resolution layers.

640x480 for 4:3 output, or 960x540 for 16:9 output, if bandwidth can run it.

Non-integer pixel aspect flags, again only for low res layers. Match 320x200 and 256x200 non-square aspects blended on a 480p/540p base output. Keep it at 60Hz

Select 50 or 60 Hz in any resolution. Ditch 70Hz, as nothing syncs to that in the PC space for compatibility. 50Hz is much lower priority, but can be done by extending vblank time and keeping pixel clock the same. If 640x400 res is still used, have it at 60Hz, again same pixel clock but longer vblank.

Palettes

Reduce from 24-bit to 16-bit, better suited to 65816, and makes a lot of addressing simpler.

5-5-5-1 masked, or 4-4-4-4 RGBA? Leaning towards the latter. Using transparency 0=opaque, 15=fully transparent is probably easier.

Have a FPGA block which separates & combines 4 values into 1, all R/W registers, avoid all the shifting. Include signed clamping when converting to the single RGB word.

Rougher ideas

Palettes are always 4-4-4-4, but direct color 5-5-5-1 or 4-4-4-4 can be used for bitmap layers? Probably best to keep it the same, but given clear displays today, the 5-5-5 would look better for full-color backgrounds.

Layers

Every layer def has these:

  • Type
  • Base pointer (could be page-aligned 16-bit, for 16MB range?, else 32-bit pointer)
  • x/y pixel scroll (16-bit wrapping). Could share these, but not a big deal to duplicate these
  • CLUT selection
  • Bit depth?
  • Clip window?
  • High or low resolution? Some modes and bit depths are low enough bandwidth to doat 480p
  • CRT emulation? only for low resolution layers. Probably a global setting, not per layer.
  • Non-integer pixel aspect flags? to match 320x200 narrow pixels or 256x200 wide pixels. Probably global setting

No-overdraw bandwidth reduction

Have multiple hardware instances of layer renderers, all fighting for external bandwidth. Render front-to-back, with transparent pixels causing the next layer underneath to want to draw that pixel. Each layer only requests individual pixels that it needs to draw, and keeps some cache for redrawing the same sprite/tile on the same line. The first layer gets The only wasted reads are when a read pixel is 0 and dispatches deeper, and 16-bit wide reads where not all the bits are used.

Alpha Transparency

Considering SNES-style 2nd pixel buffer. Either a layer could be sent to it, or some colors within one can be shunted to it while sending an empty pixel to the next layer down. This is done after front-to-back masking, so the layer stack can obscure transparent pixels, and pixels underneath that are still sought for render. There is only 1 transparent pixel buffer, but maybe if another transparent one is found (which would be lower) it could be blended in instead of replacing it. Depends on timing. Ignoring further down transparency would be a reasonable default.

The transparency level is probably determined per layer, and that is stored per pixel in the 2nd line buffer. only 2-4 bpp for transparency would be fine for blending.

Individual layers, sprites, can have a transparency override, ignoring the palette value. If they don't, transparency from the palette per color can still be obeyed.

TODO

Buffering sprites with no-overdraw is harder, probably needs its own linebuffer & alpha line buffer. Both the alpha and opaque layers need to track their own layer depth when merging together, as maybe only the alpha is visible but not the further back opaque sprite.

Indexed Bit Depth

Currently, everything is 8bpp, which is high bandwidth, and more work to create artwork.

For tiles sprites, and bitmaps, choose 1/2/4/8 bpp. Direct color 16-bit bitmaps would be separate from paletted bitmaps.

Each layer can select a CLUT. Each sprite or tile points to either a starting palette entry, or maybe a bitmask to OR into it.

Bitmaps

Option to wrap. Else, it shows blank pixels outside its range. Divmod can be done once per line.

Tiles

Option to wrap.

Option for tile 0 to be empty, without fetching the pixel data. Saves bandwidth.

Rougher ideas

Neo Geo has auto-animating tiles/sprites. 4 or 8 tiles in a row in the tileset can be cycled through for animation. (cycling through low 2 or 3 bits of tile index). Global or layer-specific config for how may frames per step.

Sprites

H-fliip at the very minimum. If V-flip and 90° (since all sprites/tiles are square sized), then all 8 orientations and flips are possible. Rotation is only available in SRAM.

16-bit sprite image selection from base pointer, based on bpp & size. Flip bits might be at MSBs of the word.

Color selection, direct for 1bpp, starting palette offset for 2/4bpp. Need to figure out something for 8bpp,

8×8, 16×16, 32×32, 64×64 sizes (2 bit selection, forget 24x24)

1,2,4,8 bpp (2 bit selection)

(or should bpp & size be for the layer? might make for simpler implementation, but varying sprite sizes are probably good. Bpp might still be a consideration for layer config

Rougher ideas

Unlimited height sprites? fixed width

8bpp color register could be used to bank a subset of colors, maybe a color range (0-7) can be cycled while others are fixed. Think of Age of Empires 1 recoloring for instance.

Select the color to be transparent? If using a fixed smaller palette, like DB16/32, then each sprite could pick a different one. Pico-8 has a 16-bbit mask for which colors to include or not, which is interesting.

Cut-out sprites wouldn't display, but would clear any pixel from sprites above it, allowing sprites below to show through. Or, it could skip the sprite immediately below if it has a pixel, masking a single sprite, which might be easier to implement.

Figure out sprite zooming. No rotation,just scaling, not inverting with this? Can grow or shrink independently in x & y. Maybe bresenham? Probably want sub-pixel accuracy, 16-bit with fixed point? Or full 32-bit fixed? x1/x2/y1/y2 dest rectangle maybe?

RLE

2 different modes, span, and pixel.