Author Topic: Vector things  (Read 1114 times)

Offline dave j

  • New Member
  • *
  • Posts: 3
  • Karma: +0/-0
Vector things
« on: January 05, 2025, 06:16:56 PM »
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 resolutions

Adding 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 improvements

Some 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 things

The 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 bullets

The 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.

Offline dink

  • Administrator
  • *****
  • Posts: 5210
  • Karma: +469/-1
  • pie? I nearly bought one!
Re: Vector things
« Reply #1 on: January 05, 2025, 08:30:20 PM »
Hi dave j,

I like your ideas, feel free to implement them and I'll certainly give them a try!

I always had this idea:
Maybe we could query the front end for its window size, and adjust the vector parameters to match it

Though I can't really say I'm too keen on the fuzzy bullets in asteroids, but, you could always make it a dip option(al) :)

best regards,
- dink

Offline barbudreadmon

  • Administrator
  • *****
  • Posts: 1164
  • Karma: +60/-2
  • Helper
Re: Vector things
« Reply #2 on: January 06, 2025, 07:45:02 AM »
The main advantage of asking the frontend for a width/height is that you can set the resolution for all vector games at once.
As for the width/height provided, it's not necessarily limited to a detection of the window's width/height, i think there is more value in providing a list of choice, and one of those choices could be "stretch to the window" for ports that can query the window size (the libretro port can't do that).

GPU rendering, why not, but that'd require several api backends if we want to cover all ports (direct3d & opengl as priorities, vulkan optionally).

Offline dave j

  • New Member
  • *
  • Posts: 3
  • Karma: +0/-0
Re: Vector things
« Reply #3 on: January 07, 2025, 11:21:50 AM »
I always had this idea:
Maybe we could query the front end for its window size, and adjust the vector parameters to match it

The weakly/strongly linked functions are envisaged to cover this.

Quote
Though I can't really say I'm too keen on the fuzzy bullets in asteroids, but, you could always make it a dip option(al) :)

You should consider that as programmer art used to test out ideas rather than a suggested final implementation. Asteroids bullets do have a glow/halo around them but it's about 40 years since I last saw one in the flesh and I wasn't looking at the screen with a view to how to emulate it at the time. Hence my comment about needing to see one.

Offline dave j

  • New Member
  • *
  • Posts: 3
  • Karma: +0/-0
Re: Vector things
« Reply #4 on: January 07, 2025, 11:33:17 AM »
GPU rendering, why not, but that'd require several api backends if we want to cover all ports (direct3d & opengl as priorities, vulkan optionally).

The link to the GPU rendering for Vectrex was an example of what could be done. I doubt I'll implement it since getting good performance on low end systems (think Raspberry Pis) really needs rendering directly to the frame buffer which would need major changes to how emulator front ends work. Libretro's render to texture and copy that to the frame buffer scheme only really works for more recent Pis and Vectrex screens are 3x4 not 4x3 - most arcade games would need nearly twice as much memory bandwidth. Even Pi0/1s can maintain high frame rates with rendering directly to the frame buffer.

API backends wouldn't really be a problem, they can all use the same format vertex buffer and the shader code is surprisingly simple, it's more the changes to enable rendering to the front buffer that would be difficult.