GSoC Week 0: Implementing the basics in Star Trek
Google Summer of Code officially started yesterday; but, since I got started a bit early, I already have a week’s worth of things to talk about. If I want to support both Star Trek: 25th Anniversary and Star Trek: Judgment Rites, I need to get moving!
Audio and the Options Menu
Since the engine could already display textboxes, the options menu seemed like a juicy next target. In fact, I barely needed to do anything to make it display; the buttons were loaded in exactly the same way as other textboxes.
This provided a nice segue into audio code; it showed me which variables corresponded to “music enabled” and “sfx enabled”. MIDI music already worked thanks to the efforts of clone2727 from years back. I added support for midi sound effects, which turned out to just be separate tracks on the same midi file as the music.
But there’s more than just MIDI - the game features voice acting from the original Star Trek cast. Their lines, plus some other audio, are stored in .voc files on the CD. To work with ScummVM, they need to be copied from the CD to the hard drive with the rest of the game’s data.
I figured it would be easy. ScummVM has a built-in VOC decoder. What could possibly go wrong?
Well, I was greeted by this. SWEET JESUS THAT IS LOUD. (I always use headphones, by the way.) However, it’s definitely the red alert sound.
OK, so after a quick look at the decoder function’s flags, I passed
Audio::FLAG_UNSIGNED to the decoder. That’s much better.
Beam me down, Scotty
With audio working, animations were next on my list. As it turned out, the transporter room was perfect for testing this; the entire sequence is just 5 objects being animated.
Did you notice that every crewman is McCoy? That’s because the other 3 officers have their animations based on McCoy’s. They just apply an xor over the face and recolor the uniforms.
After fixing that (and discovering that the timer runs at 18.206 Hz, the rate of the DOS clock), the animations looked perfect, aside from layering.
Sprite scaling would be needed before tackling away missions. Star Trek optimized this heavily; they wrote a function which constructed another function in RAM! This resulting function was just an unrolled loop which copies a row of unscaled pixels to a row of scaled pixels. This is DOS, so there’s no interpolation here.
I obviously don’t need to do anything as fancy as dynamically constructing a function in ScummVM. There’s no way I could do that portably, anyway. Fortunately, my computer is probably a hundred times faster than what Star Trek was developed on, so I’m not too worried.
With animations done, it was time for me to do movement and pathfinding.
Pathfinding is a simple system where each room has a set of waypoints. Given a source and a destination, the game locates the waypoints closest to each. Kirk then moves to the source waypoint, moves along a set path to the destination waypoint, and then moves from there to the exact destination you clicked on. This sometimes causes Kirk to walk back-and-forth when he’s starting a walk, since he might need to move backwards to reach a waypoint. I’m not sure if other adventure games do this, but it does make movement in this game feel somewhat finicky.
Anyway, just today I figured out how warps work - some of them, anyway. Each room has a set of polygons where warps occur if Kirk walks into them. However, apparently the doors in the first room of the first mission are more complicated. It seems that, since a sound effect goes with them, they need to call some room-specific code to handle that.
The game is suddenly starting to feel alive. Not only can I control Kirk, but the crewmen follow behind him when moving between screens, or do their idle animation when waiting around. It’s a small thing, but it’s rather refreshing after looking at static screens for so long.
I found an interesting error message:
Jay didn't think about pmcheck.”
Jay is probably Jayesh Patel, who is credited as one of the programmers. I don’t really know what that error message means, but at least I’ll know who to blame if I ever see it. :)
Anyway, next on my list of things is to work on the action menu and inventory menu. And, very soon, I’ll need to start looking into how room-specific logic works. Again, this is all done with x86 code and not a scripting language, so it will need to be tackled on a room-by-room basis.