Line plotting engine

A place where you can keep others updated about your NES-related projects through screenshots, videos or information in general.

Moderator: Moderators

hcs
Posts: 31
Joined: Mon Nov 27, 2006 11:34 pm
Location: NYC
Contact:

Post by hcs »

Bregalad wrote:Thanks for the idea of doing rotating polygons, it's not very exiting but it gets the job done.

I think I can now share a working version of my engine here :
http://dl.dropbox.com/u/23465629/NES_junk/vector.nes
Very nice, and in ~ 1K! Whereas my massive monthlong project does only very slightly better at the same task: vectest4

Timing on the TV for 4 full revolutions gives 20.3 FPS for yours (as expected) and 23 FPS for mine (as is hardly predictable due to a lot of dynamic behavior).

I'd love to see the source (mine is up on the vectest branch of Nestify on github), though at 1K it shouldn't be hard to read through a disassembly.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Post by Bregalad »

I don't think it's such an achievement to make it so small because there is nothing that really can take up much space.
I just have an unrolled loop that takes quite some space and the sine table for the rotation of course.

I uploaded the source here, but don't complain if you think it's a huge mess !
Especially the line plotting part which I arranged from some C code I found on the NES and which still needs some cleanup/optimisation/fixes.

To compile it you'll need WLA-DX and some other files but I think you wanted to see it just to look at it and not to comile it so it should not be a problem.

Basically how the engine function is like that :
The main difference between it and yours (and Ian Bells) is that I don't use any kind of Double Buffering. For some reason I just wanted to get rid of it whenever possible to simplify the logic, which also means faster code.
I also wanted something in the middle of the screen, the borders not being important. This leaves me the possibility to do VRAM updates at the top and bottom quarter of the screen using forced blanking.
At first I thought about a system that would update half of data at the bottom of a frame, then the other half at the top of the following frame, so that I didn't need double buffering, because all data could be updated between the end of the display section of the first frame and the start of the display section of the next frame.

In order to update as few data as possible I thought it was better to take Bell's route : Update the map as well as chars (instead of updating only chars like your demo), that way I avoid updating a lot of blank chars uselessly, at the price of having to update the map as well.
Since I use a 256x128 surface, I have 512 map bytes to update every time an image is rendered.

Finally I was able to get something even better than I planned as I was able to update 512 characters bytes and 512 map bytes in a quarter of the screen with simple partially unrolled code. I always update this even if not all characters are used, so that the timing is constant and everything is simpler, I can update all data in one frame instead of splitting it in two.

I could use either the top quarter of the screen or the bottom quarter of the screen. The problem when doing it at the bottom is that I can't synchronize easily, I'd have to wait for VBlank, then wait for the bottom of the screen, then use forced blanking and update. But all this waiting is a waste of precious CPU time, and I didn't want to jerk around DMC IRQs unless there was no other solution, so I simply decided to update at the top quarter of the screen.
This leaves the bottom section completely untouched, I didn't use it but you could put other graphics, such as text, there.

That way I have absolutely no constraint on FPS when it comes to updates, it can be as fast as 60FPS or as slow as you want and that will never be a problem.
You could even render an image, freeze it, run another program that overwrites all the RAM, then render another image, it will never be a problem.

The only real limitation (aside CPU power obviously) is the fact only 64 tiles can be used for this. I think my engine could be made to extend for updating 64 other tiles, limit the speed to max. 30FPS and use some kind of double buffering on the tiles, but I did not fee like doing that.
Pretty smooth demo. You know what I would just love? To see the NES doing animated sequences like the ones in Another World... I'm sure that a LOT of optimization would be necessary for that!
This is not really related as this is no wireframe graphics, but I don't think a lot of optimization would be needed, most of it can be pre-rendered, and use sprites for what moves. The only trick would be use solid BG tiles for inner part of sprites which are way too big to be displayed.

I don't think it'd take a lot of optimisation, but rather a lot of artistic work and a lot of ROM space.
I think there was a Famicom game I tried once with such impressive graphics, but I don't remember its name as it was in Japanese and was not "rememberable". Of course you couldn't go far in the game without knowing japanese so I didn't care much about the game but it had impressive graphics.
Useless, lumbering half-wits don't scare us.
hcs
Posts: 31
Joined: Mon Nov 27, 2006 11:34 pm
Location: NYC
Contact:

Post by hcs »

Bregalad wrote:I don't think it's such an achievement to make it so small because there is nothing that really can take up much space.
I just have an unrolled loop that takes quite some space and the sine table for the rotation of course.
Sure, but being relatively compact and fairly efficient with RAM could make it more feasible to use, potentially.
Especially the line plotting part which I arranged from some C code I found on the NES and which still needs some cleanup/optimisation/fixes.
C code on the NES? Or the net? Doesn't look too bad, I got the gist of it.
In order to update as few data as possible I thought it was better to take Bell's route : Update the map as well as chars (instead of updating only chars like your demo), that way I avoid updating a lot of blank chars uselessly, at the price of having to update the map as well.
Yeah, you win in the end if you don't have to update empty, but with the size I'm using I couldn't find a good way of keeping track of tile mappings.
The only real limitation (aside CPU power obviously) is the fact only 64 tiles can be used for this. I think my engine could be made to extend for updating 64 other tiles, limit the speed to max. 30FPS and use some kind of double buffering on the tiles, but I did not fee like doing that.
Yeah it seems like it would be straightforward to use different sets of tiles, just init NextChar to something different for each buffer. Then you can take as long as you need updating patterns and names, you could perform the swap just by switching to a different nametable.


Regarding filled polygons, I've been giving some thought to that, but gladly I haven't let it take over my life yet like this last project did. Having something worth displaying at a fairly low framerate is a big issue.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Post by Bregalad »

I meant C code I found on the net, sorry for the lapsus.
Useless, lumbering half-wits don't scare us.
Post Reply