Two Steps Forward, One Step Back


Introduction

The title of this post refers to an expression of something I encountered in CD-i development quite a few times so far. I’d make progress on a few areas of the game, to then found something else either doesn’t work right anymore or didn’t work as expected in the first place.

In this post I’ll explain one of those instances, while also giving some insight in the inner workings of the handling of CD-i input devices.

The Problem

After the last update I spend some time restructuring the code of the demo, which was mostly in a single file to prepare for turning this into an actual game. I also integrated most assets of a level into a single file format.

Making sure it still worked as expected, I then began implementing some basic controls into the game: acceleration/deceleration, moving left/right and jumping. The level is not taken into account yet, everything is essentially considered a flat surface.

One part of the game is that you have to aim your jumps, so I locked the horizontal speed during a jump. This seemed work fine, though every now and then the ship would jump straight up. This meant that at the moment of a jump, no movement was registered, even though I was holding left or right.

Input Devices

Controller Debug tool

There are two important things to know about the input devices on a CD-i:

  1. Controllers on the CD-i run on a very slow (1200bps) serial protocol, sending at most 40 updates per second.
  2. All input devices point to a screen coordinate (X, Y) like a mouse, rather than giving access to directions being held on a controller.

This means that if we want to know if we want to know if the player wants to move left or right, we have to compare the current input X coordinate to it’s previous value. Also, given that the refresh rate of the input device (40 FPS) is less than that of the graphics system, which runs at either 50 FPS (PAL) or 60 FPS (NTSC), it is possible that the input coordinate hasn’t changed from the previous frame, even if the controller is being moved.

This behaviour is well documented, and can be handled in various ways, for example by comparing the coordinates from two cycles in the past, rather than just the previous one, thereby guaranteeing there is at least one update to the input has been registered. The picture above shows a screenshot of a tool I created for the CD-i to test controllers, and the routines I use to read them out.

As a sidenote, this slow controller input is one of the reasons there are not many fast-paced games for the CD-i, and that controls in games often feel a bit sluggish.

Diagnosis

In order to find out what happens with the controls exactly, I added a temporary indicator in the game. I’d draw a line on the screen, one pixel per frame, indicating whether the controller registered left (blue), right (red) or no horizontal movement (dark gray), with a white pixel indicating the current pixel being drawn:

SkyWays with MPEG background and movement debug indicator

It clearly showed dark gray gaps in between the colored areas when I hold the controller either to the left or right, indicating that at those times no movement was registered.

My first hypothesis was that the MPEG playback introduces random lag, resulting in input being missed or not handled correctly. As a test I then disabled the background movie and ran the test again:

SkyWays without MPEG background, with movement debug indicator

And sure enough, now the gaps are gone. However, another difference was that the game and physics seemed to run a lot slower as well. This doesn’t really make sense, as I would expect the playback of the background video to use up resources, and make everything run slower.

Solution

Without getting in much more technical details, after some more digging and experimentation it appeared that the method of video synchronisation did not work well together with the MPEG playback. Instead of waiting for the start of the next video frame to, it would just continue with the next iteration of the game loop.

This meant that the controller input was being checked more often than expected, resulting in the game concluding that no input was being done. When I disabled the background video, the game synced with the video frames, and the input routines ran as expected.

When I changed to a different method of video synchronisation - there are a few different options offered on the CD-i, each with their own pros and cons, which I won’t get into at this time - the problem was solved:

SkyWays input problem solved, MPEG background and movement debug indicator

Now I only need to adjust the physics and timings to adjust for the difference in game speed. One step back indeed!

Final words

I hope this Devlog gives some insight into the unique challenges in developing a game for the CD-i. Please let me know if you find it interesting to get more of these deep-dives into the inner workings of the console, and if there are topics you want me to cover.

Comments

Log in with itch.io to leave a comment.

hoi TW.

Ik weet niet goed hoe ik je kan bereiken dus doe ik het op deze manier.

Zou je voor mijn cd-i 205/05 een usb to cd-i adapter kunnen maken?

zodat ik een muis en gamepad van deze tijd kan gebruiken?

Ik ben een cd-i fan op leeftijd maar ben niet goed in programmeren of het maken en al wat er bij komt kijken voor zo'n ding.

En dan nog een vraagje? weet jij toevallig wat ik aan de achterkant van mijn cd-i op de oranje tulip stekker ( remote in ) kan aansluiten ?

Alvast bedankt voor je antwoord.

Hoi Condor, kun je me een e-mail sturen naar cdi at nmotion punt nl - dan kan ik je verder helpen :)

Super!

When is it possible to buy the final version?

Hello! Unfortunately due to various reasons I haven’t really worked on it in quite some time, I hope to pick it up again soon and make some progress. That being said, I’m still in the early stages of the project, I can’t really make a good guess on when it’ll be done.

Fascinating, I wonder if other devs back in the commercial era experienced something similar?