itch.io is community of indie game creators and players

Devlogs

Two Steps Forward, One Step Back

SkyWays for CD-i
A downloadable game

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

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:

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:

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:

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.

Read comments (5)