GSoC Week 2: Everyone Gets Vaporized

My work this week has been the repetitive and somewhat tedious task of rewriting the code for Mission 1. It did take a while, but hardly the entire month my original schedule called for! My original schedule didn’t anticipate that I would finish the entire game within GSoC, but at this rate, it seems quite possible.

Anyway, this week’s work speaks for itself: the first mission is fully playable in ScummVM. There are just a handful of animation errors and default interactions missing (ie. using a tricorder on something when no “action” is defined for that).

Something I struggled with this week was text handling, keeping in mind that I’ll eventually want to port the French and German versions to scummvm as well. Before, that would have been extremely difficult due to the way I was hardcoding text into the code, so I switched to a system where each piece of text is referenced by a constant integer value; this will make it easy to support other languages later. And, as it turns out, almost every piece of text already has a unique “name” in the form of the corresponding audio filename, so this system was actually pretty easy to implement.

Instead of going straight to mission 2 next, I’ll be taking a break from mission-specific logic by looking into the saving system next. It’s sorely needed to make testing easier.

GSoC Week 1: Kirk is incompetent

It’s been a week and change since GSoC started. When we left off, I’d just finished implementing pathfinding. In the week since then, I’ve been busy implementing the action system, which is central to any adventure game.

The action menu and inventory

First thing’s first: we need to be able to select our actions.

This game’s interface is… questionable. You click on a body part to select your action, ie. clicking on the mouth selects the “speak” action. It may look cool and all, but the selection areas are just a bit too small. I also really dislike how the game is constantly warping the mouse around – I never have any idea where it will be after closing a menu… but alas, my job is to recreate the game faithfully, not to change the things I deem clunky.

The inventory was the next logical target. By this point, I had also figured out hotspot detection; I started to get a good grasp on how the game handles interaction between objects.

Inventory items were also a good test subject for implementing the “look” action.

Room-specific code

With the interaction system just about figured out at this point, it was time to look at room-specific code. This is what makes the missions tick; each room has a series of “event hooks” that may run when the room is first entered, when a certain amount of time passes, or when you try to vandalize a sign with a phaser.

Rewriting this will easily be the most time-consuming part of the project, and I suspect that future progress updates won’t be much more than “I finished rewriting these rooms, check it out”.

That being said, I finished rewriting the first room, check it out.

(Source: https://www.youtube.com/watch?v=sJpijZ1ukuI)

If all goes well, maybe the first mission will be completable by next week’s blog post. Here’s hoping.

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

Scaling

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.

Weirdest transporter accident I’ve ever seen…

Away Missions

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.

Other stuff

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.