I mentioned in the SDL2 resolution change fix PR (I'm grolliffe on github) that I was looking at improvments to support for vector games. Rather than making lots of changes only for people to say we don't like that, I thought I'd provide details of what I'm thinking of so people can comment on them.
Ideally, I'd implement something like
Rendering vector games on low end GPUs that I implemented in the Vectrex emulator that libretro uses. That would be a lot of work particularly making it cross platform whilst still being performant on low end systems. It would solve performance issues though.
Vector game resolutionsAdding support for extra resolutions with the current DIP switch based interface for switching between them is straightforward but is that the best way of switching resolutions? barbudreadmon mentioned in the SDL2 crash fix PR using the port to set the width/height. I assume this would be something similar to how resolutions are set for raster games in the Windows port? It will be much easier to modify the current DIP switch based approach rather than implement something similar to the current Windows approach in all the other ports. Thoughts?
I think there is value in specifying render resolution and display resolution separately:
- Low end hardware might not be able to render high resolutions but can benefit from rendering at a lower resolution and having the GPU upscale to the display resolution with linear filtering.
- Similarly, there's little visual benefit to rendering at UHD resolutions since the pixels are so small.
- Rendering at a different than displaying happens with full screen mode already.
How about...
- Define additional resolutions using the DIP switch mechanism - automatically supported by all frontends.
- Define a special weakly linked function in vector.cpp that supposedly returns the current display resolution but it really returns a special value (NULL, zeros, etc).
- Frontends that support setting resolution for vector games can implement a strongly linked version that overrides this function to return real values.
- On game initialisation, the special function is called. If NOT NULL result, adds/doesn't disable a "As display/window" option to the DIP switches.
- In res_check(), if DIP switch is for "As display/window" call the special function to get desired resolution, otherwise use values associated with the selected DIP switch. In either case, this gets checked against the result of BurnDrvGetVisibleSize() and vector_rescale() is called if they don't match.
This means we could support additional DIP based resolution switching for all ports straight away and they could later add a more convenient way of resolution switching independently of other ports.
Performance improvementsSome games (e.g. Star Wars) have very low frame rates and the game does not update every display frame which means we can avoid rerendering the screen for every display refresh. Set a flag in avgdvg_go() or vg_flush() and check it in draw_vector()?
Compilers do a good job of minimising pixel clipping tests but clipping lines instead would be better.
Lines get rendered to a 32 bit buffer and later copied to pBurnDraw, with possible format conversion. If the frame buffer is also 32 bits, we don't need to convert the format - we could even render directly to pBurnDraw.
Faster blending and other thingsThe systems most in need of performance improvements are likely those running on Raspberry Pis - particularly the earlier ones.
ARM's targetting of microcontrollers has left the 32 bit instruction set with some mini-SIMD instructions. Some of these can be useful in speeding up the vector code. They are also very easy to access using ARM intrinsic functions.
UQADD8 for blending pixel writes. Essentially does the pixel blending in a single instruction (__uqadd8() instrinsic).
Emulating this instruction on other processors using SWAR techniques is about 30% better both in space and execution time.
Scope for speeding up other things similarly.
Asteroid bulletsThe attachment is the result of my investigating ideas for Asteroids bullets. The forum doesn't allow attaching MP4 files so I've added .txt to the end. You'll have to save it and delete the .txt to play it. It's only 64K.
I'll need to see/photograph a real Asteroids machine for this as all photos/video on web are terrible as reference images.