Getting to most out of DPRAM

Started by VectorWorlds, January 21, 2020, 07:13:19 AM

Previous topic - Next topic

VectorWorlds

Hello All

I've been playing around with my Vectrex32 for a week or too now and I'm really enjoying it.  I knew at some point I would find some limits and I have.  The current challenge I have is running out of DPRAM.  I was wondering if anyone had any tips on squeezing the most out of it. 

My thoughts so far are.

1) Implement a LOD system.
2) merge as many draw calls as position e.g. if I have three boxes to draw at the same location each time then just create one sprite which has the draw commands to draw three boxes, instead of three sprites.
3) if an object is behind the camera then deactivate it.  Not sure if this is already handled by the Vectrex32?
4) Reduce model lines as much as possible.

Are there any other options / tricks that other people use?

Cheers



Andrew

jaymzjulian

#1
Firstly: As long as you have Clipping enabled, objects behind the camera will be culled.  There is this caveat that the final MoveTo will be executed, however this does NOT happen if it's followed directly by a ReturnToOrigin.

I've got a couple:

To your thoughts:
1) I do implement a clipping system.  It is, unfortunatly, kind of slow, but yours may not be because mine is kind of stupid.  But yes, this helps.
2) This actually ends up worse for me, because you can't ReturnToOrigin to reset the pen inside them, and so you end up with pen drift.  YMMV.
3) see above :)
4) This helped too - when we reduced the cycles from 300 to 150 lines or so with a redesign, that helped a lot.

I have two other hammers:

1) There is a function, 'on error', which you can use to actually call a function rather than abort - if you arrange your objects from nearest to furtherest from the player, then this will actually automatically provide you clipping and silently just drop the remaining objects.  The was what I originally did, however in my case the way the trails worked caused problems since they are giant objects which can span the entire grid, soo.....

2) ...if you have a look over on codeswap, I put a dpram multiplexor/extender there.  What this does, is split the drawing into multiple virtual frames, and increases the vectrex framerate as high as possible in order to get them on the screen quickly.  How you can do this, is by using the combination of 'on error', which will cause it to abort as mentioned above, and a function "GetCompiledSpriteCount", which will tell you how much it drew, vs how much you're left to deal with.  The version of this used in vxtron is more complicated because it has to deal with the music code and so on, but they're both the same - essentially, enumerate all of your sprites either yourself in an array, or via the GetSprites set of calls, and then disable the ones that are already drawn on the next frame, and send that to the vectrex as fast as possible.

EDIT: One thing I've asked Bob for, which he was considering at the time, is a Z-clipping option after transform - right now, you have to duplicate the transform of the vectrex32 to disable lines further than N away from the camera, and I'd obviously like to not do that - my thought was have a dynamic Z-draw distance that we reduce/increase based on hitting either dpram of frame rate limits inside the games. 

jaymzjulian

I will mention my other trick is literally just splitting the display list in 2, and doing something like this:

' make wait_recal not wait for a long time
call SetFrameRate(400)
' draw first set of objects
call display_list_a()
call WaitForFrame()
' draw second set of objects
call display_list_b()
call WaitForFrame()

Why does this work well?  Beacuse WaitForFrame() actually does the following:
1) wait for previous display list to complete drawing
2) sends the display list to the vectrex
3) returns immediatly

Meaning that as long as the call to display_list_b() takes less time than the first display list actually takes to draw (which is almost always true!), you don't actually spend any non-drawing time at all.  An example of this I use, is i'll draw the status display in one display list, and then draw the 3d graphics in a second one.

The _downside_ of all of this, is that if you do this right now, you can't use the vectrex to manage the framerate, you have to do that yourself - I actually added a feature request around this in the feature request forum, but right now that's the limitation - because each call to WaitForFrame() will wait for the framerate timer to hit zero, so you have to set a super high framerate to ensure that counter is always at or near zero.

However, to be honest for a 3d game this sort of makes sense - since you want to draw as fast as you can generally, adn use the vectrex32's timer to time your game so your gameplay isn't tired to hitting a specific draw rate.  YMMV.