Sunday 27 July 2014

Summer Retrochallenge 1: "Temple of Apshai" for the MC-10

Richard V. from the Netherlands suggested on the Yahoo MC10 group that the classic 8-Bit Basic game "The Temple of Apshai" might be a good prospect for porting to the MC-10. He posted some of the source code. The game, made for the TRS-80 Model 1/3, did look like a good prospect. It only used what seemed like simple SET/RESET graphics.
I've described in another of my posts (TRS-80 Model 1 Homage) how converting such graphics usually only involves halving the X coordinate and reducing the Y coordinate by a 3rd since the Model 1 has a 128 X 48 low res screen to the MC-10's 64 by 32 screen. One loses a little detail, but then again one has available the MC-10's 8 colors for each of the blocks, which can sometimes be used to recoup some of the detail that might be otherwise lost. Also, Model 1 games often only use 16K, an early baseline standard, which gives the MC-10 programmer 4K extra to fiddle around with.

And I needed that extra memory because Apshai is a very cleverly programmed game that used all the memory resources of a 16K Model 1 to the max, and then some. It is a game with 4 separate levels of some very complicated room maps, each filled with specific monsters, traps, secret doors and treasures.
It takes a lot of data to store all that detail.  Each level therefore was saved as a file of bytes, which could be loaded separately. I had to use a Windows utility for loading and editing Model 1 files to get at this info.  I was able to copy it into a text editor, where I massaged it into DATA statements that could then be used to create files loadable by the MC-10. I also had to create a special utility to translate hexadecimal digits, since this is the way that the PC utility presented the info.  The MC-10 doesn't have a way of dealing with hex, unlike Coco Extended Basic with its "&H" prefix.

In order to make such a large and complex program fit in memory the programmers split Apshai into two. The first half called "INN," for "the Innkeeper, is used to create a typical D&D like character with different random attributes (numbered from 1 to 18) and to equip that character with the basic items needed, which can be purchased using a randomly generated amount of starting silver. In the Model 1 version the INN program would also then load a selected level with all its wall detail (as in the illustration above) and other items and poke this information byte by byte into an area of high memory. Then the INN program would delete itself and run the DM or "DunjonMaster" program (while leaving the area of high memory with all its info intact). This is a clever way to save memory, because DM doesn't have to include all the ponderous code need to generate a character and load data from tape or disk.  Also, the information is stored in byte form in memory rather than data statements and variables. DM just has to have code for rendering the level info and running combat and moving the character.

Model 1 Basic allows programs to "chain" run other programs (i.e. to load and run another program) but the MC-10 does not. As soon as any program is CLOADED and RUN in an MC-10 all variable memory is cleared, which the Model 1 either does not do, or was made not to do by some of the more mysterious POKES in the code which I could not decipher. I had to find a way to achieve the same effect. Luckily the MC-10 obliges nicely. It has a quirky command CSAVE*arrayname,"filename" that saves any numeric array to tape. It also has a VARPTR command which allows you to find out where any variables or arrays are actually storing their data in memory. Using these commands I was able to modify all the places in the code where data was being peeked from the high memory space of the Model 1 to instances where data was peeked or poked to the memory space of a specific array. I could then use the CSAVE* command (and its opposite CLOAD*) to pass this info between INN and DM. The MC-10 only supports floating point numeric variables and arrays with each number taking 5 bytes to encode. I just had to find out the lowest value ever PEEKED and the HIGHEST and then divide this number by 5 and declare an array of that size and then, using VARPTR, I could do the same thing as the pokes to high memory were doing in the Model 1 version.

There was one catch.  Whenever Basic encounters a new variable while running a line by line interpreted program, it re-arranges memory space and tucks the new variable into an appropriate spot. This means that if you have variables that have not been used yet in a program and then get called, you have to do another VARPTR call to find out where your array has now been shunted in memory. The only way around having to do such continuous checking (with all the extra VARPTR commands this would require) is to formally declare all your variables and arrays at the start of the program. I've described elsewhere in this blog (Getting Speed Out of MC-10 Microsoft Basic) how carefully declaring all variables and putting the one's used most often first in such a declaration, is a way to speed up Basic program execution. The simplest way to declare a variable in Micro Color Basic is to include it in a DIM statement (which isn't limited to being used with arrays). So I had to carefully examine the code and then test and re-test until I had discovered all the variables that were used (in both INN and DM) and include them in DIM statements at the start of each program.  It was a tedious but necessary part of the project.

After doing all this I had a basically functional port. It was then just a question of cleaning up the code using the speed techniques outlined in the post mentioned above and adding a few bells and whistles, such as color and a few different shapes for the main monster types (creepy crawlers, undead, bugs, blobs, etc.). As usually I had to do some creative shortening of messages, as you end up with half the text width to describe anything (32 versus 64). This was made easier by the fact that the authors had clearly envisioned porting their program to other 40 character per line screen machines and thus kept everything fairly brief. As I have found with other Model 1 programs, the MC-10 just seems to run Basic code faster, so combined with the speedup techniques, the game is a little more speedy than the original.  Here are some comparison screenshots of some different versions:
Apple II
TRS-80
MC-10 Version
I had the make the character a little simple (the little chevron above).  But I was able to offset some of the drab red uniformity by adding some color to the monsters, which you can see here (a blue Ant Man):
I still have a bit of work to do on how doors are rendered, but otherwise I'm pretty pleased with the conversion, and haven't encountered any major errors since working out the basic graphic conversion kinks. In my version, its up to you to load and save the levels (array) each time you use INN and DM, but this is not very different from the original, and is even easier in the VMC10 emulator, where you simply can click on desired virtual cassette files (.C10). The extra 4K of memory allowed me to add DATA statements to DM with the values of the treasures for each level, so at least you no longer have to look them up in the manual and do a bunch of pencil-and-paper calculations to figure out the total of what you earned (it's calculated for you when you reload a level into DM). If you wish to try the program it can be found in the JimG subdirectory of the Cassette directory of the emulator (along with all my other Basic programs), which can be downloaded at: https://github.com/jggames

There is also a YouTube video which will give you a bit of an idea of how the program runs:

I have written a brief review of the program posted on the Interactive Fiction Database in which I explain why the game should be seen as more than a mere arcade RPG kill fest. A true appreciation of it really requires some engagement with the clever narrative elements laid out in its elaborate manual. There really is a mystery behind the "curse of Apshai," which the player can seek to unravel and defeat. Enjoy!

2 comments:

  1. I am pleased to read your extensive long description of how you converted the Temple of Apshai game. Greetings from Richard V from the Netherlands.

    ReplyDelete
  2. Hey Richard. Sorry I didn't respond till now.

    ReplyDelete