arbitrary geometry (ellipses, rects etc) on sprite based systems?

Started by benjaminshinobi, January 16, 2014, 05:47:52 PM

Previous topic - Next topic

benjaminshinobi

so most higher level current drawing api's (my thoughts go to processing.org) give the ability to draw geometric shapes like circles, rectangles, and lines, while a lot of older systems (NES, SNES, Genesis, etc) used tile and sprite based graphics.

How would one do this in a tile based system?

I know that it is possible (Mario Paint, Sigma's wireframe head in Mega Man X2 eventhough it was with another chip), but if you know any homebrew/cracks/intros with something similar I'd be interested to see.

But I don't need code, just in principle. Just manipulating the data in a background or sprite(s) by hand with algorithms?

Zoinkity

Rounded edges can be faked by using a mask to eliminate the portion that shouldn't be seen.  The mask could be embedded (which is really all that transparency values are) or kept externally, even as another sprite.  Draw order can also be employed, depending on the situation.

There's also the method we know all-too-well from older websites.  You take a bunch of tiles with different roundedness and string them together to form balloons or other rounded boxes.  I have a deep loathing for text bubble code.

You could draw shapes algorithmically, drawing lines of pixels that best fit the form of the shape, which isn't too far off from certain methods of finding the area under a squiggly.  However, in practice I think you'll find cheap tricks were employed.  Of course, with the SNES they added a chip to the bugger ;*) (Yoshi's Island, for instance)  They uses a lot of hardware scaling to do effects like stretching in there, so circles could become elipsis, etc.

benjaminshinobi

yeah that seems about right, it reminds me (a little bit) of all the gross stuff you had to do with HTML CSS to get rounded edges on boxes and stuff. (I think rounded edges aren't universally supported, but just sayin)

I'm looking through Cubex55's Super Nintendo longplays and it seems like you can get away with 99% sprite based stuff/creativity.

tomaitheous

They might be tile based systems, but you can setup the tiles in such an arrangement - that you make a pseudo bitmap. Depending on how many unique tiles/cells the systems can show, is how large your bitmap/pixelmap can be.

The usual method (because most older systems don't have full access to vram during active display), is have a buffer of the bitmap in local ram. Once you draw what you need to that buffer, you then upload it to vram. If the bitmap size/window is large, it might need to be updated across a few frames. If this is the case, then you usually want to have two spots in vram to 'double buffer' the image. I.e. So you don't get tearing or partial screen update artifacts.

That aside, you still need to deal with the logic of the bitmap itself. Most older systems are planar format (with the exception of the Genesis, which are linear pixels), which can make it a pain to do certain things (types of drawing/plotting/compositing). The 16bit era systems have 4bit pixel graphics, so the tendency is to leave the whole bitmap in 4bit pixel format (else you get attribute clashing). SNES has two 8bit pixel modes available, but really limits the size of the bitmap window due to using double the vram space (and the option to do double buffering). Then there's the issue of bitmap in local ram has to be in 'tile' format. That slows things down. Some Genesis games optimize the bitmap in local ram as 'columns' of 8 pixels wide. That works well rendering stuff on a vertical level (like a raycaster engine).

That's the basic idea of it.

henke37

In the end it boils down to what you can afford to do. It isn't that expensive to just do a memset for the pixels in each line of a filled shape.

Bregalad

Usually you don't want to use sprites for this but use background.

The simpler / most efficient is to assume that most of the screen is "black" and assign a specific tile for "black", or rather "blank" as if could be any colour.
Then every time you want to plot a pixel, you should find on which tile it falls on the map. If the tile is currently blank, you assign a new tile to it and start drawing it. If a tile already exists you should look it up and modify the existing version to add your pixel.

This works fine but there is several problems :
1) You are limited in the amount of non-blank tiles you can draw per frame
2) It is extremely slow, because not only every single pixel has to be calculated by the CPU, but also it has to go through this procedure for every single one of them.

The the demo I made for the NES here (with source).

benjaminshinobi

Bregalad, that is pretty sweet! Thanks!

I wasn't concerned to much about speed because I figured it would be relegated to the calculations of some special chip that would be dumping the data (ala the wireframe Sigma head boss in Mega Man X2 already mentioned), or just stored as the raw pixel information if it was a game later in the systems life where the compression was better. I was more curious into how it would be done, especially since the line would have to be "pixelized" ala http://en.wikipedia.org/wiki/Bresenham's_line_algorithm (looks like you have some version of this).