Friday, 21 October 2016

October Retrochallenge 2: Fur Trader and a Graphic Demo

I have a colleague at my university, who when I mentioned my interest in old Basic programs recalled playing a game called "Fur Trader." I told her that I had done a port of a classic simulation called "Oregon Trail" and I think she said that she had played that one too, but had really liked Fur Trader because of its connection to Canadian history.
Since I had so much fun porting and playing Oregon Trail, and I'm also a big Canadian history buff, I thought I would try to look for Fur Trader. I can almost always find a TRS-80 version of any classic Basic text oriented program so I went to one of the major archives for that system that I've stumbled across over the years and looked under the "F" filename section. Sure enough, there was Fur Trader. I then used a handy little utility called TRSTools by Mathew Reed to view the Basic source on any TRS-80 disk or cassette file (for a cassette files you must first drag and drop the file onto a virtual disk).  Here is a link to an Atari site with a page scan from the a David Ahl book of games that includes the game.

Then it was just a question of cleaning out the commands distinct to the elder TRS-80. Micro Color Basic doesn't have the DEFINT command, for example, to allow designating variables as integers. Everything must be floating point for the MC-10 so sometimes some strategic INT functions must be added to a program if there are operations that really need only an integer. In the case of Fur Trader, the program used a number of PRINT USING commands to format trading values and costs to two decimal places and with a leading dollar sign. Over the years I've built up a collection of special Basic routines to recreate the functionality of commands like this. I had one in my collection for printing values with just two decimals and no leading space (so the dollar sign can be right next to the first digit).  Here's what it looks like:
8 CC=VAL(M$):ZZ=LEN(STR$(INT(CC)))-1:I$=RIGHT$("        "+STR$(INT(CC)),ZZ):I$=I$+MID$(STR$((CC-INT(CC))+1.00001)+"000",3,3)
9 RETURN
You assign the number to variable CC and then GOSUB 8. The subroutine returns string I$ formatted to two decimal places and no leading space. You can then print it directly or add it to another string for printing or further string formatting, such as my word wrap or reverse video printing routines, which generally take M$ as their input.

As with my conversion of Oregon Trail, I added some simple graphics to try to help spice up the program a little. In this case I used my SKETCH program to draw some simple fort diagrams. Here is Fort Hochelga (Montreal):
The original title screen describes the program as follows:
You are the leader of a French fur trading expedition in 1776 leaving the Ontario area to sell furs and get supplies for the next year. You have a choice of three forts at which you may trade. The cost of supplies and the amount you receive for your furs will depend upon the fort you choose. You also specify what types of furs that you want to trade.
It's a very simple simulation. Basically you choose the fort you want to choose to trade at from a selection of 3 possibilities and the numbers of different types of pelts. The game randomly selects some hazards and trading prices depending on the fort. I'm not really there is much skill or planning involved. I haven't examined the code in enough detail to figure out whether there is anything more systematic than random numbers that determine the prices, but I think the hazards you run across on the way to the chosen fort are pretty much completely random.

An interesting bit of historical detail is that the Iroquois were traditionally the implacable enemies of the French since they had sided with their arch-enemy, the Huron, which is why your French trading party is in peril crossing Iroquois country on the way to one of the forts.

My hope is that when my son Charlie gets back from his first term at university that he might be able to help program in a brief snippet from a coureur de bois paddling song to add to the intro, or as part of a "travelling" interlude routine. He's my MC-10 sound programming expert. We generally use my MUSIC program to type in notes and then print a list of them as SOUND #,# statements to a text file using the MC-10 emulator's print to file function.

Here's a video of the program as it currently stands:

Another little program I made this month was a simple graphic demo. I subscribe to a number of Sinclair ZX81 Youtube channels. The ZX is the spiritual predecessor of the MC-10. It was obviously the inspiration for the kind of computer the MC-10 is-- an ultra-low-end entry level 8-bit. However, that market had largely disappeared by the time the MC-10 was released in 1983. The classic 8-bit home computers (Atari 800, Commodore 64, Coco) had simply come down enough in price to make ultra low budget machines unnecessary (except for poor flinty losers like me). But I digress. Unlike the MC-10, the ZX thrived in the brief heyday of ultra-low-budget-computing that it helped create. It has lots of fans and lots of Basic programs written for it. It also has a standard graphic resolution of 64 X 48 block graphics, which is a resolution the MC-10 also has in the form of its SG6 screen mode.

Youtuber ZX81 Programs ZX81 has put up a bunch of videos of simple, but interesting Basic programs written for the ZX81. One of these was called "ZX Type-in Program Pattern 2:"

Since the MC-10 and ZX81 share a 64X48 graphics resolution it was pretty easy to port the code I could see briefly listed in the video. The MC-10 lacks a PLOT command, but it can still do SG6 graphics with a few tricks using POKEs. My port uses a special Basic SG6 plotting routine I developed HIRES_SET&RESET2.TXT and not Greg Dionne's M/L plotting routine that I normally use in most of my SG6 programs. However, the MC-10 version is still faster than the venerable ZX81, but the ZX came first and blazed the trail!
Anyway, thanks to ZX81 Programs ZX81 for posting his videos and thanks to the archivists who have contributed all the wonderful free Basic software for the TRS-80 available on the Net. And thanks to Creative computing for it interesting simulation and my colleague Janice Tulk for the suggestion for another fun porting project!

Wednesday, 19 October 2016

October Retrochallenge 1: Deep Scan

As with many of my programming projects I got my inspiration for Deep Scan via some retro video watching on Youtube. I was browsing game videos from the NEC PC6001. I like keeping track of stuff about the NEC PC because it uses the same neon green wonder of a video chip, the Motorola MC6847, as the MC-10 (and Coco, Dragon, VZ200, etc.). Retro Gamer Z posts a lot of play-through videos for the NEC PC. I've subscribed to his channel, so I see when he posts new things. He posted a video for a game called "Deep Scan."
It was in hires and has lots of wonderful sound (the NEC has a fancy sound chip). Most certainly it was written in machine language. However, I thought the concept would work quite well in Basic. I also felt that I could probably bring all my best tricks to bear on making the animation fast. The resulting game, also called Deep Scan in honour of its inspiration, is pretty fast, although I am under no illusions that it is M/L fast. I'm just happy to make it as fast as possible within the restrictions of Micro Color Basic.
The main action of the program takes place in a tight FOR/NEXT loop starting at line 20--the number I commonly use for the main loop in most of my programs. The most commonly called subroutines usually start at line 1. Line 0 usually dimensions all the variables and then jumps to the startup routines, such as displaying the instructions, which are all located at the end of the program. I use only single letter variables and as few of them as possible, which includes recycling variables for multiple functions if possible. I declare the most commonly used variables in the DIM statement first, since I have been told they are looked up by the basic interpreter from a list in order of declaration or first use (i.e. further down the list takes longer to look up). I use pre-calculated arrays to store the correlated set-reset x/y locations for all the possible screen locations that a sub might be at. That way I can use an array to store each sub's location and the x/y locations for its continuously firing torpedoes, but when I need to re-fire from its current location, I don't have to calculate the new x/y location for its specific screen position. The program just consults the pre-calculated x/y array locations for the current position.

When it comes to checking for the characters hit by the depth charge I use a 255 element array for all possible characters with numbers stored in them usable by ON/GOTO or ON/GOSUB commands. The commands can then act as a single check for multiple possible actions depending on an character occupying the location to which the depth charge will move next. The next location is searched simply by PEEKING the screen memory location of that position and then consulting the array using the number returned. So, the blue water character of 175 is left as zero, whereas the characters for the subs have 1s put in their array locations, and torpedo character has a 2. This way, an ON/GOSUB line#1,line#2 routine can be used to either simply allow the depth charge to continue falling (the 0 value defaults to jumping past the ON/GOSUB options) or the sub hit or torpedo hit routines (line#1,line#2).

I use the same array to store numbers for the various actions of key inputs. Since the program only uses A for left and S for right and the Space key for depth charge, I just need to store a 1, 2 or 3 in each of the array locations corresponding to the ASCII values of each of these keys. Then, one ON/GOSUBline#1,line#2,line#3 will handle what to do when any of these keys is pressed. One ON/GOSUB therefore can do the work of three IF statements, which speeds the program's execution and provides Basic with something like the functionality of a SWITCH statement used in higher level languages.

Other speed measures include having torpedoes only check for hits once they move above the dark blue water.  Otherwise they just keep moving up. In other words they don't interact with other subs, other torpedoes, or the player's depth charge. They just keep moving up to the level of the Cyan sky. Once there, a check is made if they hit clear sky (Cyan) or the ship (Black). Sky=have the sub fire another shot. Black=ship hit. I think in the original NEC game shots can be blocked by other subs, torpedoes or the depth charge. By simplifying the complexity of the interactions between virtual objects, limiting the objects to single SET/RESET pixels or characters (the torpedoes), or single line PRINT@ strings (the subs and ship), some reasonably speedy animation in Basic can be achieved. In other words compromises must be made between speed and complexity, but I think virtual worlds can be created in Basic that are complex enough for reasonably good game play.

That being said, I know my games will have a limited possible interest for people attuned to modern computer gaming. Perhaps they might appeal to a very small number who remember the simple Basic type- games of the early 1980s with great affection. Perhaps they might only appeal to me. Yet, when it comes to a hobby it doesn't matter how many other people share one's interest. It was certainly fun in and of itself, to spend a number of hours crafting a "type-in" style game.  And it certainly took a few hours, and multiple false starts at thinking I had finished.  First I had to refine the startup screen a little to make it a little more interesting than the rudimentary one I started with:
This version also had a few fixes. I had to play enough games to notice that sometimes the bonuses could be randomly plotted in locations to the extreme right that the sub couldn't reach it with its depth charge. I also tweaked the number of lives awarded from a random number of 1 or 2, to just being 2. The game was tough enough that giving 2 lives if you survived 3 screens (when the bonuses appear) seemed reasonable, and more fair than a random number. Such fine-tuning can only come from playing the game a lot. I also eliminated a fourth size of ship, which I found too hard to play. You want to avoid unfairness and arbitrary death as much as possible, which can be tough to achieve in Basic games (or impossible, at least according to my Xbox jaded son).

My last major fix was that I noticed that I had a completely unnecessary array. I had a whole array for all the possible screen locations for the subs. Then I had an array which held a number that I incremented or decremented to point to that array. Stupid. I don't remember the rationale, but I just needed to store the actual screen locations for each sub and increment or decrement that, not a pointer to an array with  screen locations. It just goes to show that you never know whether you have fully streamlined a program. Continuous play and reexamination of the code can turn up efficiency improvements even after you think you've done everything possible. Most people will probably find it difficult to discern any substantial difference in speed between the various versions, But such subtle and obscure perfections are what hobbyists live for....

If you try the game try please let me know what you think (unless you are my son Charlie--XBox has ruined you boy, at least for the purposes of Basic Beta testing:). And any suggestions for game improvements or new features would certainly be welcome.  My next Retrochallenge post will be about two other programs I worked on earlier in October, Fur Trader and a graphics demo from the Sinclair ZX81.

Saturday, 1 October 2016

Miniature Golf by Mitch Voth



Thanks to the help of Darren and jdiffendaffer on the MC-10 Yahoo group I was able to figure out the esoteric features of SG6 graphics mode to port a miniature golf game by Mitch Voth from the 16K TRS-80. I used Greg Dionne's M/L USR utility (a BASIC subroutine that pokes a USR "SET" function into memory for setting SG6 64X48 graphic points on the screen). I had to figure out a way to do without a point function by simply looking if the byte location of the screen map changed after plotting (i.e. no change means the point is already lit in that byte region). My conversation with Darren and J.D. did help me figure out how to reset a point, which allowed me to get a nice cursor flash function built into my port. Darren figured out a M/L USR "POINT" function (which can also be poked into memory), which I hope to use in future projects or possibly to improve some existing games. I've added that routine (HIRES_SET&RESET2.TXT) to the UTILS directory of my Github site.

Thanks again to all these folks for their help in my programming projects.

As can be seen in the pictures above I used my SG6 Basic text plotting routine to print the 3 message lines at the top of the TRS-80 original. Of course I had to condense the information to just the course #, par # and player's name (limited to 5 characters). Luckily the original game already doubled the pixels to draw the maps and ball on the 128X48 screen of the TRS-80, so representing it on 64X48 screen was no problem. I just had to half the pixel plot values and remove the second pixel plot done for all the SET commands in the original program. The original also used a period character for target for each hole. I used a red dot instead, and therefore had to re-program a different piece of code to judge when a ball enters the hole.

I have also made a couple of little fixes to my programs lately. My son Charlie left for Dalhousie University so his bedroom in the basement has been reverting (somewhat) back to my MC-10 "man cave." I also made a number of Retrocomputing presentations at our local Cape Breton CaperCon gamer and sci-fi convention. As part of that project, I got an old android tablet to work as a WAV file player for my real MC-10s to replace my tape cassette player. So I have been playing a lot of my games on the real hardware lately. I noticed that I hadn't properly entered the map data for the last map of my port of Robot R-29.  I also noted a misspelling in my port of Lance Micklus' version of the classic Star Trek III game. His version is very rich and complex. Here's a link to a video of my port from the TRS-80 of TREKIII:




And here's a video of my version of Miniature Golf (Note: I have added a few speedups since this video was made):




Thanks to John and Neil for mentioning my Robot R-29 project in their last Coco crew retro podcast. They gave me a little good-natured ribbing about being a Basic programmer but I still highly recommend their podcast for people interested in all things TRS-80. We Basic programmers are used to hearing such sentiments from the M/L and higher level language master race;)



Next post (hopefully) a Retrochallenge project of some sort.