Sunday, 18 March 2018

RetroChallenge 2018/04: Forest of Doom Port--Beware the Shadows!

Bruce Moore's "Forest of Doom" has been a bit of a sensation in the Coco community. I thought it would be nice to try to convert it to MC-10 so I sent away for Bruce's book and the code to download the game. When the book arrived I fired up Vcc and loaded up the program and LLISTED it to a text file and started pouring through the code. It is a complex game and it took a lot of play testing and watching Stevie Strow and Crew playing it to figure it out. There was a mysterious machine language routine embedded at the heart of the basic program that seemed to do a lot of different things. I'm still not sure if I have figured out everything that it does, but based on watching game play and playing it myself I have uncovered at least the following basic functions:
·         clearing to bottom of screen from current cursor position
·         screen bounds checking for cursor movement on map screen
·         time keeping and sound for countdown till next hit
·         time keeping for checks for wandering monsters
·         “Inn now” secret key press (still don't know how many it will allow)
There may be more mojo hidden in there, but I'm not sure. Bruce has told me he'll try to dig up the source and send it to me, by the time of Cocofest.  He's busy with another project to follow up on FOD.

The big challenge in converting the program was coming up with a memory efficient way to try to recreate all the nice music and sound in it. It is impossible to recreate everything using just sound commands, but I tried to come as close as possible without the help of my son Charlie, who is away at university. I came up with a simple routine for encoding a string of note letters and a number (for length) which could be sent to a subroutine.  I came up with this:

0 DIMN(21)
1 CC=1:FORC1=1TO63STEP3:N(CC)=VAL(MID$("073093102119134141154166176180189196200206212217219221227229232",C1,3)):CC=CC+1
2 NEXT:GOTO10
4 FORCC=1TOLEN(M$)STEP2:SOUNDN(ASC(MID$(M$,CC,1))-64),ASC(MID$(M$,CC+1,1))-48:NEXT:RETURN
10 M$="G4G4G4A4B4B4":GOSUB4

Line 1 is the initialization of the routine with the note info. You create a string M$ and GOSUB4 to call the routine. Line 10 demonstrates such a string and call. The routine uses ABCEDFG and then HIJKLMN and OPQRSTUV for the next two octaves up. I actually used the O-V range to encode some flats needed for FOD, so that version is slightly different from the generic one above.

Like my port of Caves of the Unwashed Heathen I also had convert the graphics into simple strings of semi-graphics characters. Vcc allowed me with the help of a little basic subroutine, to print these out to the printer port (i.e. text file on my PC). Then I could edit them into text strings condensed as much as possible to save memory space. I also had to figure out ways to use some of the graphics for multiple purposes, such as the iconic red tree, which is used for the title screen and final death screen. On the Coco version there is no need to use such memory saving techniques.

I worked out rough equivalents for many of the sound routines from the original, at least to the best of my limited musical abilities  Here’s a vid of an Alpha version:
I have left it to Bruce to decide if he would like to pursue sharing my version with the wider MC-10 retro community.  I think he's waiting till Cocofest where he might be able to have some of his game testers take my version a spin to see if it really works. I’m sure MC-10ers would be very pleased to participate in the excitement he created in the Coco fold.  In the meantime I am continuing to play and bug test. Here is a vid of the latest version with the most recent music and sounds:

Had to do a lot of condensing to make space for some new sound routines related to the combat subroutine. When I was doing this I came across some REMed lines, that I think were an attempt to implement some special behavior of the Shadows on the first level. One of the clues given by Innkeepers is that "A shadow is not always what it first appears."  However, I had never found anything obvious in the code in terms of printed messages that would indicate anything special about shadows. But I did notice two REMed lines referring to monster #5. A quick look indicated that this was the number for shadows. It looked like what the lines were supposed to do was present a message when you were attacked by a single shadow (which can only happen on level 1) that you were being attacked by a Shadow and then swap the monster number for a random monster (1-10). Not sure why it might have been taken out but it might have been because of complexities with the monster names which are processed to deal with plurals or single monsters and then saved in three strings for different purposes.  Or maybe the shadow routine got put in the mysterious machine language helper program somehow.  In any case, I re-implemented the REMed lines and made them report an attack from a shadow and then choose and list a random monster in the upper area of the screen. So if you don't check to confirm what is attacking  you, it could be something you don't expect!  Beware the shadows, they may not be what they first appear!

1 comment: