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.
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:
There is also a YouTube video which will give you a bit of an idea of how the program runs: