Keen Dreams - Porting Back To DOS

Here is where to post about the latest Commander Keen fangame or modification you've finished, a new website you've made, or another Keen-related creation.
Post Reply
NY00123
Vorticon Elite
Posts: 508
Joined: Sun Sep 06, 2009 19:36

Keen Dreams - Porting Back To DOS

Post by NY00123 »

LATE POST EDIT (Dec 24th, 2016): Edited download link since Dropbox' "Public" folder is expected to become private by March 2017.

A few words of a warning - This can take a little while to start up. If your computer is capable of running DOSBox with cycles=40000 then the time to pre-process sound effects might be about 5sec.

https://www.dropbox.com/s/63nzz52m8npzq ... 8.zip?dl=0

So this is basically a silly attempt of mine to grab the Keen Dreams DOS sources, and then make them usable with the data from the 2015 port as currently available from Steam and IndieGameStand. As in this port, you can switch between EGA and CGA graphics from the control panel, and also show the high scores. Note that as in the 2015 port itself, the CGA data is really EGAGRAPH under disguise.

Currently the game data should (probably) be available from any of these store pages, but be warned that it can be updated at any moment!
http://store.steampowered.com/app/356200/
https://indiegamestand.com/store/1317/keen-dreams/

One way in which the 2015 port greatly differs from the original DOS versions, is the way sounds are stored and played back. Basically, the original PC Speaker and AdLib sounds were recorded as 16-bit 44100Hz waveforms, and then compressed using DPCM and Huffman. The Huffman part is more-or-less the same as done for the DOS releases, while the sound data itself consists of second-order differences of samples. The last sample in each sound effect should be silence/centered, but I kind-of cheated and assigned silence to the first one instead. Haven't spotted a great difference, though.

Since this is still a DOS port, it means that I took advantage of the existing Sound Blaster and Sound Source code pieces. Some changes had to be done, but this is the main path.

If you're wondering about the file "EXTGRAPH.KDR", it's a small set of alternative gfx chunks used in the Sound Panel. These are just chunks from the DOS versions that should be used instead of unrelated replacement chunks from the 2015 port (like a fullscreen toggle).

A great issue with supporting the sound effects is memory usage. After making a few experiments, eventually I downsampled everything to unsigned 8-bit data at ~7042Hz, not only due to memory constraints, but also since the last sample rate was appropriate for the Sound Source (the same rate is also used in Wolf3D).

I also "borrowed" the version of ID_MM from the Catacomb 3-D sources, in order to take advantage of a couple of XMS and EMS memory pages.

Furthermore, I used lemm's work on a function called "VW_ShiftlessMaskBlock", and related. It's basically a way to support on-the-fly sprite shifting, while storing just one copy of each sprite in memory.
Last edited by NY00123 on Sat Dec 24, 2016 8:53, edited 1 time in total.
User avatar
K1n9_Duk3
Vorticon Elite
Posts: 781
Joined: Mon Aug 25, 2008 9:30
Location: Germany
Contact:

Post by K1n9_Duk3 »

That sounds impressive. It's nice to see people still doing DOS stuff these days.

I don't have the 2015 version, so I guess I won't be able to test this myself.

So the re-release has all sound effects stored in waveform instead of the original AUDIO/AUDIOT format? Do you know why they did that instead of emulating the OPL and PC Speaker on the fly?

I was kind of forced to do something similar in my ReDuke project (PC Speaker sound effects are converted into waveform sounds at startup), because the BlitzMax libraries don't provide the interface to emulate the PC Speaker on the fly. This caused some timing issues, where you could sometimes hear the same sound starting to play multiple times in a split-second when multiple actors in the game played the same sound at the same time. The reason was that wave sounds start playing immediately when the PlaySound() function is called, while the original PC Speaker sounds need to wait for an interrupt in order to start playing frequencies.

Does the Keen Dreams port have the same issues or did they implement some kind of sound manager to prevent this from happening?
Hail to the K1n9, baby!
http://k1n9duk3.shikadi.net
User avatar
Levellass
S-Triazine
Posts: 5265
Joined: Tue Sep 23, 2008 6:40

Post by Levellass »

I too do not have the 2015 version. But this sounds interesting.
What you really need, not what you think you ought to want.
NY00123
Vorticon Elite
Posts: 508
Joined: Sun Sep 06, 2009 19:36

Post by NY00123 »

Thanks for your comments on that "DOS port/mod"!
K1n9_Duk3 wrote:So the re-release has all sound effects stored in waveform instead of the original AUDIO/AUDIOT format? Do you know why they did that instead of emulating the OPL and PC Speaker on the fly?
Originally, the DBOPL emulator was used for the OPL sounds, and PC Speaker sounds were also generated on-the-fly. This was done in the Omnispeak project (https://github.com/sulix/omnispeak/blob ... rc/id_sd.c) and later found itself in a Keen Dream SDL2 port (https://github.com/sulix/keen-dreams-sd ... er/id_sd.c). The latter was eventually used as a base for the port available from Steam.

However, using DBOPL, which is available under the GPLv2+, is a problem if you want to distribute a binary on platforms like Steam. While there are at least a few LGPLed alternatives, the developer of the KDreams port (sulix, aka Multimania) decided to record all sounds, by running Romero's MUSE tool under DOSBox. PC Speaker and AdLib sounds were both recorded.

Apart from the licensing issue, this also simplifies the relevant code pieces, as you simply need to feed the SDL callback with the relevant recorded samples.
K1n9_Duk3 wrote:I was kind of forced to do something similar in my ReDuke project (PC Speaker sound effects are converted into waveform sounds at startup), because the BlitzMax libraries don't provide the interface to emulate the PC Speaker on the fly. This caused some timing issues, where you could sometimes hear the same sound starting to play multiple times in a split-second when multiple actors in the game played the same sound at the same time. The reason was that wave sounds start playing immediately when the PlaySound() function is called, while the original PC Speaker sounds need to wait for an interrupt in order to start playing frequencies.
I assume there was no issue of a so-called "sound priority" here? (e.g., totally ignoring the priority.)

As a side-note, an issue specific to using a PlaySound() style function can be found on the Android platform. While there is an Android port of SDL2, and you can use the SDL audio callback as usual, there's often a quite noticeable sound latency that you simply cannot avoid. This looks like a limitation of Android itself, and/or specific Android-powered devices.

I suspect an interface for a pre-recorded sound (like the above PlaySound()) will work better, since there are other apps in which I don't notice such a latency.
K1n9_Duk3 wrote:Does the Keen Dreams port have the same issues or did they implement some kind of sound manager to prevent this from happening?
I'm not aware of any such an issue.
Post Reply