Drawing an ECG

A heartbeat with TriAPI

I’d been looking forward to making the ECG heartbeat monitor for a while, and began proper work on it yesterday. While I didn’t have any initial ideas on how I wanted to implement it, I knew that I wanted to go down a dynamic route rather than making an animated sprite for each condition. A few years back I’d tried to make an ECG for fun. That system worked by drawing your heartbeat shape in Photoshop and then importing it into a custom that analysed the lines and built an array of coordinates where the lines connected to one another. That got saved into a text file that was parsed by the game and then I drew along from point to point using FillRGBA on the HUD. I wanted to have a fade effect, so I essentially had to do a huge amount of calls to FillRGBA to achieve the trail of the heartbeat. While it worked, it was unfortunately very slow indeed.

I decided against this approach for re-implementing it this time, and wanted to go with something more efficient. Out of sheer blind luck, I happened to be playing Resident Evil 1 on an emulator for something unrelated, when I noticed that the ECG was freaking out in the inventory menu. I realised that the ECG in even the first Resident Evil was actually drawn dynamically, as in my version the points and lines were going all over the screen. That gave me inspiration for how to make mine, so I started taking a look at TriAPI. This is a simple API for drawing triangles from the client.  It supports very basic OpenGL-like functions, such as drawing vertices, setting blend mode and displaying textures. I saw that it supported drawing lines, which is exactly what I needed.

I got to work with mapping out the basic shape of the heartbeat for every health condition by recording game footage and stitching together all frames. I traced over that in paint and mapped out dot-to-dot where each vertex would need to be to draw the heartbeat. Luckily for me, Paint displays the pixel position under your cursor, so I could quickly build up an array of all the pixel offsets of each vertex. The good thing about drawing lines in TriAPI is that, because it requires a start and an end vertex, you can set the colour of both separately, causing a gradient between the two. Therefore if I set the start colour to be black, the end colour to green (or orange/red, depending on health condition) and the rendermode to additive, I’d already have the fading trail effect. The final step was then to step through each line one by one, stretching it from its start point to end point and then fading away as it moves to the next vertex pair.

After a bit of tweaking and iteration, I got a result I was fairly happy with. There are still some visual issues, such as not fading the gradient perfectly between neighbouring lines, but for now it’s good enough. It’s also not as “high-resolution”as it could be. I’m using about 11 vertices, but more could be added to soften the shape of the heartbeat. I also need to do some extra tweaks as the line is going over the border slightly.

The final step was to create the ECG art behind the heartbeat, and the border around the edge. I made this pretty quickly in Photoshop by tracing over the Resident Evil 2 art. The final result looks like this: