Tuesday, January 31, 2012

Astute observers of my videos might note that the "FAHRFALL" on the title screen has been changing a bit. I wanted something not only that would reflect the relative sizes and speeds of each scroll from the background of the game but also that would be readable and that would look reasonably good. After a lot of tweaking, I think that what I have now is looking just about right.

Another little detail for the alpha release is that I have added an "ALPHA TEST 1" label to the title screen. This should clarify which version is running if there are any issues reported with the binary. Also, it clarifies that this is not the final version of Fahrfall.

Alpha Test Release

I wasn't sure about how to release Fahrfall. I fully expect to release the source code at some point. However, I haven't yet gone to the trouble of adding all the proper license info and such to the source tree. For that matter, I haven't even decided on a proper license for the source. I'm not at all sure that the average CoCoNut is prepared to deal with having obligations under the GPL! :-)

Anyway, for now I figure that anyone interested in Fahrfall mostly just wants to play it. Frankly, playing Fahrfall and commenting on it is the best way for anyone to help me right now. So, I decided to just do a binary release along with a license to allow anyone to (re-)distribute it.

Don't be too freaked-out by the license file! I am just allergic to releasing software without some sort of license attached. This license just gives you the right to distribute the Fahrfall binary in case you want to pass it around. I lifted it from the license file that a number of hardware vendors use to distribute their firmware for use with Linux. If you somehow feel it is too restrictive, then feel free to contact me so we can work something out!

The disk image contains a BASIC loader for the machine language binary. So you should only need the following command to run the game:

RUN "FAHRFALL"

I tested the above on a CoCo2 using DriveWire 4. All seems well for that setup. If you are using an emulator, well, then YMMV.

I have done a lot of development using the "-quickload" option to the MESS emulator. So, you can imagine my surprise when Fahrfall crashed in MESS when loading from a disk image! I am prepared to believe that Fahrfall is doing something wrong, but I don't have time to figure that out right now. Given that Fahrfall is running fine on real hardware, figuring-out what might be wrong with MESS isn't my highest priority.

Another emulator that is popular with CoCoNuts is VCC. I tested Fahrfall with VCC and while the colors seemed wrong (i.e. too dark), Fahrfall seemed to work alright. Of course VCC claims to emulate a CoCo3 -- so Fahrfall should not have run at all!! Well, whatever...as I said, YMMV...

Add some comments below if you have trouble using the binaries! Also, feel free to comment below or to contact me off-line if you find bugs with Fahrfall or if you have serious suggestions for how to improve the game.

So, RetroChallenge has been fun! I had intended to work on Fahrfall as an exhibit for CoCoFEST! anyway. But the opportunity to be part of a little competition was motivating. If nothing else, the deadline helped me to keep some focus. Now I just have to catch-up with my DVR, etc... :-)

One problem with having a retro-computing hobby is that so few people seem to grok what it is all about. So, it is rewarding to have an outlet to reach a few other people with the same kind of wierd interests as me. It was even more rewarding to find that my silly little blog on Fahrfall was interesting enough to gather over 1200 page views from around the world in less than a month's time! Who is the wierdo now? Hmmm? ;-)

Fahrve Marches On!

Anyway, no one should read this as the end. Fahrfall isn't done yet! I might slow-down a bit on the blog posts, but there is still some progress to be made. Plus, I have to get Fahrfall ready to exhibit at Maker Faire NC and CoCoFEST! I recently got a Pelican Case for my CoCo stuff, so I might expand to some other vintage computing events as well -- feel free to suggest some venues! :-)

The Fahrfall updates will continue for a while yet to come. As always, please continue to watch this space!

The first steps toward animating Fahrve were actually done back when the player object first started moving. The first was the separation of the draw and erase routines, allowing Fahrfall to erase a different figure than what it is about to draw. The other step was the introduction of different icons for odd starting positions and even ones. This basic infrastructure allowed for at-will changes in Fahrve's appearance depending both upon his position and upon what he is doing at any given time.

Fahrve's glide across the platforms was disturbingly unnatural. I originally wanted him to turn and walk in each direction, but the low resolution of the video screen made creating suitable artwork for that difficult to imagine. I decided to settle for simple up-and-down arm movements, something like early versions of Donkey Kong.

I considered making a multi-frame sequence for each step, slightly different for steps in each direction. But I started by simply lifting one arm and one leg in the odd frames, and the opposite arm and opposite leg in even frames. The result was good enough that I decided not to complicate the sequence any further for now.

That wasn't too bad, but that left Fahrve frantically pumping his arms and legs even as he fell through the air. The player object in DOWNFALL falls with his arms above his head, and I thought Fahrve should do the same. So, I implemented a set of draw/erase routines for falling on both even and odd pixel boundaries. Now he looks like he actually knows what he is doing as he moves vertically between platforms!

Winding Down

Animating Fahrve is one of the last big "gotta have it" points for Fahrfall. There are still plenty of tweaks and features to add (e.g. music), but Fahrfall is now a usable game that will need some playtesting and feedback to fully develop. Soon it will be time for Alpha testing!

Saturday, January 28, 2012

One thing that Fahrfall has been sorely lacking is sound effects. Well, the wait is over... :-)

Audio Sources

The CoCo has two internal sources for generating audio. One of those is a 1-bit output for generating square waves, similar to what was available on the original IBM PC. The other is a 6-bit DAC for generating 64 levels of unsigned PCM audio. Also available is an audio source line tied to the external cartridge slot. A handful of cartridges were available for the CoCo that took advantage of this feature, including the Tandy Speech/Sound Cartridge (SSC). A fourth potential sound source is the cassette port, but that source seems impractical for use in a game like Fahrfall.

The best option both in terms of maximizing the sound quality and in terms of minimizing the cycle budget cost would be to use an SSC for music and sound effects. The SSC includes both an AY-3-8913 Programmable Sound Generator and an SPO256-AL2 Speech Processor, making it capable of producing a wide variety of sounds with limited intervention from the CPU. Unfortunately, the SSC is somewhat rare these days and many potential CoCoNuts don't have an SSC at all. I may save SSC support as a back-up plan in case I can't get Fahrfall to produce CPU-driven music to my satisfaction. For the near term, I will stick to a few simple sound effects that I know the CPU can drive already.

Using the DAC to produce sounds would be the next best option in terms of sound quality. Unfortunately, producing non-square waveforms at any but the lowest of frequencies will require timing more precise than Fahrfall is prepared to do at the moment. However, the vertical synchronization timing should be able to produce a few effects based on square waves. For now, Fahrfall will stick to use of the 1-bit sound output.

Timing The Waves

What can one do with a 1-bit output and a 60 Hz timer? Well, alternating between '0' and '1' on that output every cycle will generate a low, raspy tone. Modulating that tone can produce a "tic-tic-tic" sound, and we can pretend that the "tic-tic-tic" sounds like a series of footfalls as someone walks across a moving platform. :-)

It just so happens that the background scrolls in Fahrfall are already running during every frame cycle, each following a repeating sequence of 2, 4, 6, or 8 frames. Hitting the 1-bit output in each half of the 2-frame sequence provides the basic tone, and enabling or disabling the output every other frame of the 4-frame sequence provides the modulation for the "tic-tic-tic" sound. Using a variable to control the value written to the 1-bit output when it goes "high" (so that sometimes "high" really just writes a '0' value, the same as "low") allows for the sound output to happen without any conditional branching. This makes it very cost-effective to have the footfall sound available when the player object is moving on the platforms and to still be able to turn it off when the player object is standing still or falling.

In addition to the footfall sound, I also wanted a sound to go along with the end of each game. Since the game is already over at that point, it is OK for everything to stop while such a sound is played. So, I expanded Fahrfall's "game over" routine to poll the horizontal sync signal for about a quarter of a second. After each horizontal sync signal, the LFSR is advanced and the data from the LFSR is used to drive the 1-bit sound output. This produces a white noise output that is slightly disconcerting -- just enough to let the player know that the game is over and that they should feel bad about it... :-)

The addition of these simple effects makes a difference when playing Fahrfall. It just feels a bit more "real" now, and the white noise at the end of the game is just enough of a scold to make you "feel" it -- hopefully enough to make you want to play some more! In the future, I want to add music to the title screen and some background music to the game itself. But for now, this seems to be good enough.

The end of this month's RetroChallenge event is coming soon. It seems appropriate to make something available for that event's judging. I haven't yet worked-out the details, but I will at least release a loadable binary or a diskette image suitable for use with an emulator or on a real CoCo.

My ambitions for Fahrfall are reasonably modest -- I want something fun to play that makes the most of the CoCo's resources. The progress so far is good, but I don't really think I have reached my goal. I definitely have some more features in mind for Fahrfall, so I reckon that the coming release will have to be considered an Alpha release. I'll probably even put something on the title screen to indicate that status. :-)

Mini Maker Faire

The area in which I live is somewhat rural. Living in an area like this has a lot of advantages, but support for lots of quirky hobby groups typically isn't one of them. Fortunately, I have connected with a few other crazies in the area and we have formed The Alamance Makers Guild with the hopes of synergizing with one another and of eventually forming a physical hacker- or maker-space.

Why is that apropos for this blog entry? Because we have initiated planning for a Mini Maker Faire event at the Holly Hill Mall in Burlington, NC on Saturday 28 April 2012! Along with whatever else our club has there, I intend to have a playable Fahrfall setup as part of the exhibit. If you are anywhere near local to me then please consider coming-out for this event! If you just can't make it to Burlington on that day, I am also planning to have Fahrfall on display at Maker Faire NC in Raleigh on 16 June 2012.

CoCoFEST!

Years ago, there actually were magazines dedicated to the CoCo. Chief among those was The Rainbow, and the publishers of that magazine organized a number of conference events dedicated to promoting the CoCo. The last of those events was more than two decades ago...or was it? In fact, a dedicated group of CoCoNuts in the Chicagoland area has kept that tradition alive all the way to the present day with the annual "Last" Chicago CoCoFEST!

Over the years, CoCoFEST! has transformed from a computer show to a "swap meet" and then to more of a social event. I assure you that the No Minimum Bid auction is not to be missed! In any case, this is the big event in the CoCo community each year and I intend to be there. I hope to have Fahrfall more-or-less finished by then, and I'll haul my CoCo there for an exhibit. This is your chance not only to play Fahrfall but also to rub elbows with the brilliant mind behind it! :-) It is also a good opportunity to integrate oneself into the CoCo community. If you are a budding CoCoNut, then you need to find your way to Elgin, IL on 19 & 20 May 2012!

More To Come

It's Friday night as I write this, so I suppose that the weekend has already started. I'm a bit too tired for anything beyond a little poking at Fahrfall's edges this evening, but I intend to get serious about getting my Alpha candidate ready on tomorrow and Sunday. More updates coming soon, so stay tuned!

Wednesday, January 25, 2012

I am still dragging a bit after my weekend road trip. Plus, my days off from work have left me playing a lot of catch-up. So, I haven't had much time this week for progress on Fahrfall. Fortunately, I still have some background topics I would like to cover! :-)

Due to the peculiarities of an analog video signal, anything which produces rapidly changing graphics (e.g. a video game) needs to account for the proper timings in order to avoid flicker on the screen. Racing the Beam gives a good overview of the concerns here, albeit from the perspective of the Atari 2600 instead of the CoCo. Anyway, the important point is that most drawing in the screen memory needs to occur during the non-visible portions of the video signal.

The VDG is helpful in this regard. It provides a signal as the end of the visible screen is drawn. This signal is available on one of the PIA pins that can generate an interrupt. Alternatively this line can be polled, which is how Fahrfall uses it. Upon detecting the end of the visible screen, Fahrfall proceeds to erase the player object and the platforms, then redraws the background scrolls, the player object, and the platforms in their new positions. This not only gives a stable, flicker-free display of those objects, but it also ensures that they are displayed correctly even if another object has moved over them in a previous frame.

The VDG also provides a signal to indicate the end of each line on the screen. This occurs at a rate of approximately 15.7 KHz. Currently, Fahrfall does not make use of this signal. In the future, this signal will probably be used to time the playback of audio data samples for some background music. Adding this feature will be delayed for a while, since processing interrupts at that rate is terribly expensive and adding polling throughout the code will likely be a bit ugly.

Finally, the score and the flame effect are actually updated at the very beginning of the visible display area. This is acceptable for the score because it doesn't get updated very often anyway. As for the flame effect...well, it is supposed to flicker, right? :-)

Mind The Budget

This brings us to the topic of cycle budgeting. The normal clock rate for the CoCo is ~0.895 MHz, which would give us approximately 14914 cycles per frame in which to work. Of that, approximately 10752 cycles happen during the visible portion of the video signal, leaving only around 3920 cycles for the non-visible portion. (The numbers don't quite add-up due to some rounding-down at several stages of the cycle computations.) It's too bad that drawing on the screen is the most difficult and time consuming part of the act...at least so far!

The CoCo does have a little trick up it's sleeve here -- the "hi-speed poke". There is a setting for the SAM that doubles the CPU clock speed to ~1.79 MHz. The problem is that the VDG kinda chokes when that setting is enabled, causing the video display to be garbled. That limits the use of the "hi-speed" setting to times when video is not being displayed -- exactly when we need the boost! So by enabling this setting after the end of the visible display area and disabling it before we get back around to the beginning of the next visible portion of the display, we essentially double the amount of time we have for display updates -- ~7840 non-visible cycles, hooray!

Keeping Tabs

So, how do we know if Fahrfall is holding to it's budget? Well, the technique I mentioned in an earlier post gives at least a rough estimate of how much of the visible budget is being used. Of course, that is the fattest part of the budget anyway... Exceeding the non-visible budget results in display corruption at the top of the screen, but that doesn't really tell you if you are still under budget but getting close to exceeding it.

That leaves the tried-and-true method called cycle counting. Cycle counting is tedious and error-prone, and it can be more of an art than a science in many cases. Many assemblers (including mamou) can assist by providing estimates for individual instructions, but manual analysis is usually required to determine the aggregate cost of a given routine. For interested readers I recommend Nick Bensema's Guide to Cycle Counting on the Atari 2600. Obviously it is written for the 6502-based processor in the Atari 2600. But, the basic techniques will be similar for other 8-bit processors (including the 6809).

As for Fahrfall, I did an analysis of my non-visible drawing routines. That includes updates for the background scrolls, the player object, and the platforms. Right now, that is taking around 7000 cycles -- a bit tight, but hopefully that at least leaves enough room for playing some background music in the future. Beyond that, there is probably room for a little optimisation there and perhaps I can move some of that work into the visible area so long as I properly account for the timing of the video signal.

I haven't done any analysis on the visible area so far, since that budget is so big and so little work gets done there at this time. Let's hope that there aren't any big, ugly monsters waiting to eat me there!

Anyway, I hope you have enjoyed this little diversion. Please continue to watch this space for more updates on Fahrfall!

Monday, January 23, 2012

No game seems complete without some sort of title screen to introduce itself to the world. The title screen sets the stage for the game itself, and serves as a "branding" tool for the project. A good title screen is a nice little bit of polish that can make a game stand-out. Therefore, Fahrfall needed a title screen! :-)

Keep It Simple

One could put a lot of effort into producing a title screen. In fact, I put a whole day into something that I thought was going to be fairly simple. In fairness, I may not have been at my best after a whirlwind roadtrip to Atlanta over the weekend. :-) In any case, I wanted to avoid getting carried away with embellishments.

I wanted to have a credible title screen for Fahrfall -- something attractive and reasonably polished. I also wanted to have something ready to turn-in for the RetroChallenge Winter Warmup at the end of the month, and I still have some other things to do. So, I decided to stick to some simple effects, a copyright notice, and a simple instruction on how to start the game. I think this covers the basics and still gives a good impression of the game.

Reflect The Game

The basic elements of the title screen come from Fahrfall itself. The top of the screen replicates the top of the main game screen -- the flame effect and the score displays. Beneath that is an animated graphic of "FAHRFALL", with the size of the letters, the rates of movement of the letter groups, and the colors of the pixels reflecting the corresponding elements in the background of the main game screen. Beneath that is a static copyright notice reflecting me as Fahrfall's author. At the bottom is a flashing "PRESS BUTTON" instruction on how to start the game. The overall aesthetics are pleasantly simple while reflecting the main game screen.

Credit Is Due

The DOWNFALL title sequence contains a number of credits and "shout outs" to a variety of folks. This seems common with homebrew games, and probably has a lineage back to the days of "demo coding". I would like to do something like this in Fahrfall at some point, but it can wait until things are farther along. Similarly, some sort of self-playing "attract mode" would be a nice addition in the future. When I add something like this, it will probably take the form of messages periodically replacing the copyright notice or somesuch.

Anyway, there it is -- I think Fahrfall is looking fairly good! I hope you are as excited about Fahrfall's progress as I am. Stay tuned for more updates!

In the answer I gave to this question in a Facebook comment, I joked about "trying to make all those 'one percent' CoCo3 owners feel jealous for a change". In truth, for a long time almost anyone with a reasonably serious interest in the CoCo had at least one CoCo3, probably as their main CoCo system. The CoCo 1/2 bits of their collection mostly piled-up around the house, the products of trying to keep old CoCo stuff out of the landfill. Most CoCoNuts only kept the old systems around either to run the handful of software that didn't run on the CoCo3 or as fodder for electronics projects that could use some computer control -- remember, we've been at this for a lot longer than for how long the Arduino has existed... :-)

With that said, we are finally reaching the point where CoCo 3's are becoming a little scarce. Also, recent years have shown an uptick in interest amongst nostaligic former CoCo users. Today, many potential CoCoNuts don't even have a CoCo 3. Many more have nearly-useless CoCo 1/2 systems laying about the house doing nothing. So, producing a game that only runs on the latter has a certain appeal to me.

Fight The Good Fight

I have developed software for the CoCo 3 in the past. In particular, I developed a digital video player for the CoCo 3. That was a fun project, and during that project I brushed against many of the unique features of the CoCo 3. I know that the CoCo 3 platform is relatively luxurious in comparison to the CoCo 2.

But, my hobby is retro-computing and especially retro-programming. What is the point of all that retro-stuff if it isn't to re-create a taste of the past? A past where programmers struggle to make the most of what little they had? It is this struggle that intrigues and excites me.

The video capabilities of the original CoCo platform are much more limited than those of the CoCo 3. The flexibility of the interrupt generation hardware is much more limited as well. And the only timing sources available are the horizontal- and vertical-sync signals from the video hardware. Making something entertaining and fun on this platform seemed more like the kind of challenge I wanted.

As I mentioned in Basic CoCo Architecture, the basic CoCo design is copied from a diagram in the SAM datasheet. A charitable person could use that fact to explain why there were a number of CoCo clones, including the Sampo Color Computer, the Prologica CP400, and the Micro-SEP. The British-born Dragon was at least polite enough to swizzle the design enough to avoid being branded a true "clone". Nevertheless, the Dragon and the other clones are all close enough to the Tandy CoCo that lots of software written for one will run on the others more-or-less as well.

The existence of these (near-)clones means that there is international demand for CoCo 1/2-compatible software! Owners of these machines cannot use software developed for the CoCo 3. These old machines are yearning for new software! How can I deny them that? ;-)

Hit The Road

Well, hopefully that answers the question of why I am targeting the original CoCo platform. I hope to be able to support the CoCo 3 as well in the long run, but I haven't yet solved all the technical answers of how I will do that. CoCo 3 owners can rest assured that they will be able to play Fahrfall too -- eventually... :-)

I'm going to be doing a little travelling over the weekend, which will limit the amount of attention I can pay to Fahrfall. I will try to squeeze-out a post or two, but there won't be a lot of progress on the game itself. I am taking Monday off as well, so maybe I can catch-up a bit then.

Wednesday, January 18, 2012

Sometimes a game isn't really a game unless you can keep score -- am I right? Well, at least that's true in the arcades... :-)

How Long Can You Fall?

Fahrfall isn't about running though a maze while eating dots, nor is it about jumping barrels or shooting aliens. It is all about staying on the screen for as long as possible. So, the basic scoring mechanism will be based on game time. Future versions will likely have bonus items to grab or maybe other score modifiers based on how you play the game. But for now the score will really be a glorified clock.

The frame loop is timed based on the vertical sync signal from the video output. Hooking this sixty Hertz timer seems like a natural place to start. But, bumping the score on every frame leads to scores that advance too quickly to read -- fast enough to roll the score in about five hours.

Maybe it is unrealistic to think that anyone would play Fahrfall for five hours...but I can dream! :-) Plus, I don't want the score to roll prematurely when I later add bonus items and whatnot. So, I introduced a countdown timer that gets reset every time the score is advanced. Now I have the count increasing four times per second. If someone plays Fahrfall for seventy-five straight hours then they deserve to see the score roll over!!

Count It Up

The obvious vessel for the score in memory would be a multi-byte binary integer -- something like an "unsigned long" in the C programming language. Updating an integer like that is relatively simple, even in an 8-bit processor's assembly language. Unfortunately, such a representation is not directly compatible with the CoCo's display. Repeatedly converting from a multi-byte binary integer to a display-compatible format seems like a waste of CPU cycles.

The VDG uses hexadecimal values 0x30 through 0x39 to represent the normal digits '0' through '9' respectively. If the score is kept in a compatible format, then the score can simply be dumped to the display whenever it is needed. This is easily accomplished by implementing a cascaded decade counter based on the value in the lower nibble of each byte. This technique uses only a few more cycles than incrementing a multi-byte binary integer and it avoids the need to do any further conversion for displaying the score.

Every arcade game needs a high-score display! People like having that objective to reach, even if such an achievement is always ephemeral. So, after the current score is incremented, Fahrfall compares it to the recorded high-score. The comparison starts with the most-signifcant byte and proceeds until it finds two uequal values. If the current score is higher, it is copied to the high-score position. There is only one trick here -- the high-score is displayed using digits that use a color set that is the inverse of the current score's color set!

The VDG is using hexadecimal values 0x70 through 0x79 for the high-score digits. So, the score comparison needs to convert each byte value before comparing the score digits. Also, if a new high-score is achieved then the current score digits need to be converted before moving them to the high-score area. This is a simple detail, but without this the two score displays would look exactly alike.

Getting There

So, Fahrfall now has one more feature implemented. It is starting to look like a real game! Hopefully I will be able to nail-down a few more basic features in time for the end of the RetroChallenge Winter Warmup. I might even have time for a few extras by then as well -- stay tuned!

Tuesday, January 17, 2012

Now that we can move a little man around the screen with the joystick, how do we keep the man from falling through the platforms?

On The Level

Fahrfall keeps track of three levels of platforms at any given time. The platform data is stored in an array of three structures, with each structure tracking information for the platform level within a specific section of the screen. As platforms transition from one section of the screen to another, the corresponding platform data is correspondingly transitioned from one structure in the array to another.

The data in a platform structure tracks the horizontal configuration of a given platform (i.e. where the holes are), the color data for display of that platform, and the vertical position of that platform. The vertical position of the player object is compared to the vertical position of each platform to determine if they are on adjacent vertical lines. If so, the player's horizontal position is checked against the platform's configuration to determine whether or not a collision has occurred.

Under The Table

The platform configuration data is stored as an 8-bit mask. Each bit represents eight pixels worth of platform, so the configuration data spans the width of the 64x96 screen resolution. But, a direct comparison between the player object's horizontal position and a platform's configuration data would be meaningless.

To check for a collision, either the platform's mask needs to be translated into a series of horizontal position ranges to check or the player object's position needs to be turned into a mask for a bitwise comparison. Using the player object's position as an index into a lookup table performs the latter task quite nicely. Once the player object's position mask has been retrieved, a bitwise AND operation between that and a platform's configuration data can determine if there is a collision. The player movement routines now can react to a collision by moving the player upward when the platforms move upward.

Leap Of Faith

The above works great except for one special case. If the player object is positioned on the bottom line of the screen, no collision will be detected even when a new platform enters the screen directly beneath it. Fahrfall does not track information for off-screen platforms, because off-screen platforms literally do not exist. No one can detect collisions with platforms that don't exist yet!

When playing DOWNFALL (the game that inspired Fahrfall), it is sometimes necessary to take a leap of faith off a platform that is about to disappear from the top of the screen. In those cases, you don't always know where you will be able to land. Having a platform appear beneath you at the last second before you fall off the screen is really cool, and I wanted Fahrfall to provide that same possibility. So, I added a special collision detection check for the case of a new platform entering the bottom of the screen. Now, all seems to be well. :-)

In the video above, I have done a little hacking to produce a semi-playable demo. On top of the working collision detection, I have added code to move down whenever the player object is not on top of a platform. I also sped-up the platform movement a bit to add to the excitement of the game. There is no scoring, and the movement of the player object is still a bit "wrong". But, what is there is enough like a game both to be somewhat entertaining and to give a good impression of where Fahrfall is going.

So Far, So Good

I'm excited about how far Fahrfall has come! It is looking fairly good, and so far there have been few complications. Wish me luck on keeping-up the pace!

I don't know how much more real progress I'll be able to make this week. But I do have some more background topics to cover in the meantime. If there is any significant development progress on Fahrfall, I'll be sure to post about that as well.

Monday, January 16, 2012

I haven't said much about Fahrfall's actual progress lately. Real life makes plenty of demands on my time during the week, so there wasn't a lot of real progress to report up until the weekend. Now the weekend is over -- so how are things going?

When last we left Fahrfall, I had just demonstrated my ability to read the joysticks. Making a player object move on the screen seemed like the next logical step.

Something Sketchy

I had originally intended to start with a very simple player object -- a square or something, probably all one color. That would have let me progress with the game logic without having to decide on the artwork in advance. But something motivated me to sketch-out some variations of a player icon late last week. So rather than toying with a generic object, I decided to skip ahead with one of my sketched figures!

The easiest technique for drawing an object on the screen would be to simply block copy a source image to a specified target location. Two nested loops would control the operation, copying one byte at a time for a certain number of bytes. Use of a "magic" value (probably zero) for a data byte could even enable sections of an image to be transparent. This technique probably suffices in many situations. But the transparency checking imposes a non-zero cycle cost that is repeated every time the player object is drawn.

At present, I am using a different technique. I have a custom routine for drawing the player object. That routine loads a color used in the object, then uses a combination of 8- and 16-bit writes to fill-in the parts of the object which are that color. All of the colors are done in turn, and transparent sections simply are not written. This technique allows for transparency without requiring a number of conditional checks at runtime. Unfortunately, I haven't calculated the cycles used this way -- so, I don't know if this technique is actually better than the block copy! I should verify that at some point..

The drawing routine is paired with an erase routine. The erase routine is a bit simpler, since it only needs to use one color (i.e. black). Whenever the player object moves, the erase routine blacks-out the player object at its old position. Note that the combination of the fixed black background and the background scrolls being regularly redrawn allows for the erase routine to avoid having to actually restore any background bits.

With a draw routine and an erase routine in hand and the ability to read the joystick, everything is in place for player movement. For a simple demonstration of this, the player is drawn on the screen at a starting position. During each frame period, the joystick is read and a new position is calculated for the player, one byte to the left or right or one line up or down. During the vertical blank period, the player is erased at its old position and redrawn at its new position.

As noted in the video, there is a problem this technique. The 2-pixel per byte display format makes it impossible to move one pixel at a time on the horizontal axis. The solution is relatively simple: a second pair of draw/erase routines is added with the object displayed one pixel to the right. The horizontal movement routine alternates between even and odd draw/erase pairs in between every left/right byte change. This results in smoother horizontal movement, and avoids leaving the player object "stranded" one pixel away from the edge of the screen.

Sound Collision!

The collision detection routines shown above are minimalistic. They are really just enough to keep the player on the screen, but are obviously insufficient for the premise of Fahrfall. In the next update, I'll talk a bit about how Fahrfall detects collisions between the player object and the platforms.

Saturday, January 14, 2012

So, I was reading Nick Marentes' blog for his game project for the CoCo3 called Fortress. Nick was kind enough to add an entry for Fahrfall to his Tandy Color Computer Games Workshop site, so I thought I would check-out some other people's projects there. Anyway, while reading Nick's blog I stumbled across a reference to a little technique that I thought might come in handy sometime.

Timing Is Everything

In reference to one of the screenshots on his blog, Nick says "The red portion can be ignored. It's the way I test the speed of the code by setting the border color to red when I start my routine then reset it to black when finished." That way, you can get a visual indication of how much of your cycle budget you are using without having to scan the assembler listings to count the cycles by hand -- what a cool idea!

There is just one catch...Nick is developing for the CoCo3. That machine lets you specify the color of the background separately from everything else, so it is easy to switch it at will. The VDG used in the original CoCo models doesn't allow for that -- the background color is predetermined by the video mode and (in some cases) the value of the CSS pin. In the case of the alphanumeric/semi-graphics mode used in Fahrfall, the background is always black.

Still, that is a cool technique. Surely we can find a way to use it? Well, yes! You see, the VDG is fairly dumb about its video settings and it mostly just goes along with whatever values are on its configuration pins at any given moment. So, nothing stops you from switching to a different mode more-or-less at will. So for example, you can switch to a graphics mode for part of the screen and back to alphanumeric/semi-graphics for the rest. That doesn't give the prettiest display imaginable, but it does the basic job.

Size Matters

Switching back and forth between modes paints an ugly picture, but carelessly choosing the modes involved can make things worse. In particular, choosing the wrong alternate mode can leave a big "glitch" at the border between the two modes. In my test case, it made it look like the top of one mode was curled like a piece of paper. I fixed that by ensuring that I was switching between two compatible modes -- modes with the same number of bytes per line and the same number of lines per screen. In my case, the mode to partner with the 64x96 SG12 mode was the 128x96 "color" graphics (CG3) mode. This paring still made for an ugly display, but it was stable and recognizable enough to potentially use for debugging a timing-related problem.

I intend to talk more about timing issues in a later post. I was just excited about discovering this technique from Nick's blog and wanted to share!

Have Your Say?

Oh, one more thing...I'm thinking of changing the score text at the top of the screen to use the orange text color set rather than the green.

Any comments from the peanut gallery? Which color do you like better for the scores? The author reserves the right to ignore you, of course... :-)

Friday, January 13, 2012

Some people have asked me about the development environment I am using to produce Fahrfall. I suppose I could pretend that I am hunched over a CoCo, inches away from a television, furiously typing on the old chiclet keyboard while I wait for the assembler to finish writing to my floppy disk drive. But in reality, I'm not quite that hard-core!

Development Host

Instead, I am comfortably seated at the controls of my laptop running Linux. If it matters, I use the Fedora distribution of Linux. I edit code in vi, and I use make to build it. My assembler runs from a command-line as well, of course. OK, maybe I am a little bit hard-core. ;-)

The assembler I use is called mamou. I believe that the mamou assembler is derived from Motorola's freeware 6809 assembler. It also includes some functionality to assist in targeting the CoCo platform (such as support for the CoCo's machine language binary format), and some features to mimic other assemblers from the CoCo's past. The mamou assembler is part of a package of tools called Toolshed, which also contains a number of other utilities related to using the CoCo and for developing CoCo software.

I haven't yet reached the point with Fahrfall where I need macro support in my assembly language sources. But if/when I do, I will probably just use m4 for the job. Stop booing! I used m4 in my CoCo3 Digital Video Player project in order to support building different versions both for the SuperIDE device and for the emulated hard drive interface that many CoCo emulators support. It isn't that bad! No seriously... :-) Well, it gets the job done for me anyway.

One last little tool that I use for lots of development is minicom. This requires some code running on the target, of course, and hardware as well. But I do find that having that little terminal window into the soul of the CoCo provides a lot of power for software development.

CoCo Target Hardware

Here is a secret -- I'm not developing on a CoCo! Well, not exactly... I am using a TDP-100 for my development target. The TDP-100 was a clone of the CoCo produced by Tandy and sold through stores other than it's own Radio Shack. I guess the marketing folks back then thought this was a good idea? Well whatever -- it is the same as a CoCo on the inside. This particular box has been modified to output composite NTSC video so that I don't need an RF tuner to use it. It has an internal speaker added as well, FWIW.

As I mentioned, I am using a serial connection as part of my development. The hardware I am using is the "Wireless Drive Pak", which seems no longer to be available. Anyway, it is basically a clone of the RS-232 serial expansion that Radio Shack sold for the CoCo years ago. But, the serial port itself is replaced by an off-the-shelf Bluetooth module that implements the RFCOMM profile. This allows me to hack on the CoCo from across the room -- awesome!!

CoCo Target Software

So what is on the other side of that serial link? A 6809 monitor program, of course! The one I am using is MON09, available as part of the Micro-C for the 6809 package from Dunfield Development Systems. I ported it to run as a CoCo ROM as part of another project a couple of years ago. I used that code to replace the EPROM that came with the Wireless Drive Pak originally.

Having a monitor program available is insanely handy, especially for initial development and experimenting. Easy commands allow for you to poke at memory and registers for a variety of purposes, including video mode experiments that would be painful to do at the actual CoCo keyboard. Loading code over the serial port is trivial, especially since mamou outputs the S-record format that MON09 expects to see. And did I mention that the monitor supports breakpoints, single-stepping, and automatic disassembly of the code? It is hard to imagine doing CoCo work without it.

Wrap-Up

Well, there you have it -- a nice overview of my development setup. If you have any questions about what I'm doing or how I'm doing it, then feel free to ask. If you have any suggestions to make it better then I would love to hear those as well.

Thursday, January 12, 2012

The video in the CoCo comes from the Motorola 6847 VDG. The VDG is configured by means of several digital signals on its external pins. The CoCo uses some of its PIA outputs and some clever wiring to control the VDG configuration.

The VDG offers a handful of video modes which can be grouped into 4 basic categories: 2-color "resolution" graphics modes; 4-color "color" graphics modes; 4- or 8-color (+ black) "semi-graphics" modes; and alphanumeric modes. In the CoCo and its cousins, the last two categories are combined using the clever wiring mentioned above. Also, one of the "resolution" graphics modes can be used to produce a different 4-color mode by means of NTSC "artifact" colors.

Resolution Graphics

I'm not sure why the VDG designers chose to use the term "resolution" graphics for the 2-color modes. I guess it's because these modes pack more on-screen pixel resolution into the same video buffer space as their 4-color counterparts.

Anyway, in these modes pixel values are encoded with one-bit per pixel, or eight pixels per byte. Any "0" bit values correspond to black. The "1" values correspond to either green or buff (i.e. almost white), depending on the value of the Color Set Select (CSS) configuration pin. This encoding is available in 128x64, 128x96, 128x192, and 256x192 resolutions. The last of those is really only available on black and white televisions due to "artifact" color effects on NTSC monitors.

NTSC Artifact Colors

The combination of the way the NTSC video system encodes color information and the common practice of combining Luma and Chroma signals together into a Composite video signal creates the possibility for certain anomalies when interpreting such video signals. In particular, the signal created by the 256x192 "resolution" graphics mode tricks a color television into producing 4-color pictures! The effective resolution of this mode then becomes 128x192.

The black/green color set produces drab, muddy greenish colors that usually aren't very useful. But the black/buff color set produces a black/white/orange/blue color set. The only real problem is that the encodings for the orange and blue colors (which use "01" and "10" bit encodings) are determined randomly at each boot (i.e. sometimes they use "10" and "01" instead). Most CoCo games that use this mode start with a title screen that asks for the player to reset the CoCo until the screen objects are the correct color.

Mapping images to this color set is not as horrific as it may sound -- the results are reasonably tolerable. The presence of black and white in this color set helps a lot, especially for the stark scenery of a "space shooter" game or something similar. This is probably the single most popular graphics mode for CoCo games, at least for the commercial-grade ones.

There are also some "artifact" colors that use wider and mult-line bit patterns. These modes rely on the nature of a CRT picture tube and not on the nature of the video signal itself. As such, they really don't work on LCD screens and often don't work on "newer" CRT televisions either. In reality, this form of "artifact" colors is really more similar to dithering than to anything else. Given these facts and the relatively poor state of documentation for the expanded set of "artifact" colors, I won't go into any real detail about them here.

Color Graphics

The "color" graphics modes encode color values with two bits per pixel, or four pixels per byte. Depending on the value of the CSS pin, these color values select a color from either a Green/Yellow/Blue/Red palette or a Buff/Cyan/Magenta/Orange one. This encoding is available in 64x64, 128x64, 128x96, and 128x192 resolutions.

In these modes, all of the pixels encoded in a single byte must come from either one of those color sets or the other. It is possible to have both color sets used on the same line, but that requires the CPU to actively change the value on the CSS pin at the correct times while the given line is being drawn on the screen -- tough! A somewhat easier task would be to use different color sets in different horizontal slices of the screen, but that approach does not lend itself well to common playfield layouts. In practice, most usage of these modes simply picks one color set or the other and sticks with it for the entire screen. Expanded use of the CSS pin usually just isn't worth the cost in CPU cycles.

(Note: the only commercial CoCo game known to have used this "on the fly" technique of modifying the CSS pin is Dragonfire.)

Alphanumeric/Semi-Graphics

The VDG has a 64-character set of alphanumerics built into it. These display with a dark (but not quite black) background and a foreground that is either green or orange depending on the CSS pin value. One of the configuration pins can cause these characters to be displayed "inverted", with black foregrounds and green or orange backgrounds. The normal CoCo text screens use black characters on a green background.

The VDG also offers two "semi-graphics" modes. These modes offer lower resolutions (64x32 or 64x48), but with more available colors (at least for SG4). Unfortunately, the colors are specified for groups of pixels rather than for individuals ones.

The Semi-Graphics 4 (SG4) mode divides a character-sized block into 4 pieces (2x2), and allows each piece to be specified as either black or as a single color common to the other colored pieces of that block. All eight colors (Green/Yellow/Blue/Red/Buff/Cyan/Magenta/Orange) are available for each character-sized block in this mode.

The Semi-Graphics 6 (SG6) mode divides a character-sized block into 6 pieces (2x3), and also allows for the blocks to be either black or a common color. This mode offers a choice between the same two 4-color sets as in the "color" graphics modes, with the CSS pin used in the same way to choose between them as in those modes.

The alphanumeric mode only needs six data bits for describing each character, and the SG4 mode only needs seven of them. In the CoCo, these facts are exploited to allow for switching between alphanumerics and SG4 characters automatically based on the data in the video buffer. The high order data bit is fed into the VDG pin that selects between alphanumerics and semi-graphics modes. The next highest order bit is fed into the VDG pin that inverts the alphanumeric character display. This allows for semi-graphics, inverted alphanumeric, and non-inverted alphanumeric characters to share the same display without any heroics from the CPU!

The SG6 mode is handicapped by all this cleverness. The bit used to select semi-graphics mode would normally be a color selection bit for the SG6 characters. But now for SG6 to be active at all then that bit must be a "1" -- this effectively limits the color choices to one of two (or one of four by switching the CSS pin value). The resulting diminished usefulness of the SG6 mode is probably no great sacrifice. In most cases the 64x64 "color" graphics mode is probably about as attractive as the SG6 mode anyway, considering both visual quality and resource usage. In any case, what is done is done and we must live with a crippled SG6 (or just ignore it).

SAM+VDG Semi-Graphics

As documented in the datasheet for the 6883 SAM, the combination of the SAM and the VDG allows for the creation of three new graphics modes based on the SG4 encodings! In fact, it can be used for a few more modes as well -- but the SG4-based ones are the most useful. :-)

By itself, the VDG handles its own memory addressing during video buffer reads. In order to share access to display memory between the VDG and the CPU, the VDG has an input that will force it to relinquish the memory bus to the CPU. However, unfortunate timing of that signal can result in video display glitches as the VDG is starved for information about what to display. A big part of the SAM's job is to coordinate between the VDG and the CPU in order to prevent such glitches. As part of that job, the SAM handles the video addressing on behalf of the VDG and the VDG's memory addressing pins are (mostly) ignored.

The SAM can monitor some of the VDG's output pins (including one of the memory addressing pins) in order to keep track of what part of the screen the VDG is drawing at any given time. But the SAM cannot determine everything it needs to know like this. So, part of the information used to configure the VDG must be used to configure the SAM as well. This is where opportunity rears its head!

The VDG normally re-reads the screen buffer twelve times for every line of alphanumeric/semi-graphics characters -- once for every physical screen line of those characters. When you configure the SAM and the VDG identically, then the SAM replicates this policy. But if the SAM is configured for a bigger display buffer, the effect is for the SAM to re-read the screen buffer fewer times before advancing to the next line of character data. This can double, triple, or sextuple the number of "characters" on the screen, while simultaneously reducing the height of each "character" to half, a third, or a sixth of the original character size. Using this technique with the SG4 encoding produces three new modes known as SG8 (64x64), SG12 (64x96), and SG24 (64x192). Just like SG4, each of these new modes allow for eight colors (and black) to be available on-screen at the same time!

Fahrfall's Graphics Mode

Perhaps ironically, the Color Computer is often criticized for its relative lack of on-screen colors and especially for the particular colors available. I can't do much about the latter, but I did want Fahrfall to demonstrate just how colorful the CoCo really can be. That narrowed the choice of video modes either to one of the SG4-based semi-graphics modes, or perhaps to one of the "color" graphics modes using well-timed CSS manipulations. The movement in the background of Fahrfall and the fact that the player object could be just about anywhere on the screen at any given time made the CSS manipulations seem impractical.

I also wanted to keep the game performance at an entertaining and playable level. Sure, everyone wants a nice "high resolution" display like the ones in the arcades. But the games in the arcades often had hardware assistance either for playing audio or for pushing video objects around the screen (or for both), whereas the CoCo only has the CPU to do those things. So the SG12 mode was chosen in hopes that its 96 lines would be more manageable than the 192 lines of an SG24 display.

From my experience with the CoCo3 Digital Video Player I learned that color resolution can be a good substitute for spatial resolution in graphics. Consequently, a 64x96x8 mode sounds like it is in the same ballpark as the 128x96x4 mode used in many CoCo games. The comments I have received about the Fahrfall videos posted so far seem to indicate that people think it looks alright. So, hopefully the SG12 mode is a good compromise between beauty and performance.

Phew!

Well, this one went longer than planned...I hope it was worth it! At least the CoCo hardware got a little more coverage, and I got to share my thought process for picking SG12 as the video mode for Fahrfall.

The weekend will be here soon -- wish me luck on finding some time to get a player object moving on the screen for Fahrfall... :-)

Wednesday, January 11, 2012

Real life demands attention, particularly during the week. So, I haven't been able to concentrate much on Fahrfall for a few days. However, I did find some time to figure-out how to read the joystick -- that should be handy!

Analog Joysticks

The CoCo uses analog joysticks that return separate analog voltages for both X and Y axes of rotation. The values of these voltages range from 0-5 Volts, with the value corresponding to how far in the left/right (or up/down) direction the joystick is pointing. These voltages feed into one half of the CoCo's analog multiplexor. From there they can be routed individually to one side of the CoCo's analog comparator.

The button on the joystick is a digital signal, and once it is read it needs no conversion. But the analog values coming from the joystick need to be transformed into digital values in order to be useful to the computer. The CoCo has no Analog-Digital Converter (ADC) hardware. So, how is this handled?

The other side of the CoCo's analog comparator is connected to the output of the CoCo's Digital-Analog Converter (DAC). The output of the comparator feeds into one of the PIA ports. So all the CoCo has to do is route the desired joystick axis to the comparator, cleverly manipulate the DAC values, check the comparator result, and interpret the results in order to generate an approximation of the joystick's position. Simple, right?

At least one of the decades-old programming references I have for the CoCo actually recommends walking through all 64 possible DAC values in order to perform the analog-digital conversion. I suspect that a binary search starting with the MSB of the DAC would be much more efficient (~6 iterations). But I think my way is even better than that!

Get To The Point

Analog joysticks are fine for flight simulation, "precision" pointing, and maybe some other applications. But most people seem to prefer digital joysticks for arcade-style games, since what you really want to indicate is direction rather than position. I can't make the CoCo use digital joysticks, but I can make it treat the joysticks as if they are digital.

The algorithm that I am using divides each axis into three zones, one at each end with a "dead" zone in the middle. This allows me to find all the information I need for each axis with only two comparator cycles. For now I am using a 40/20/40% split for the zones. This leaves a dead zone that roughly corresponds to the width of the "trim" adjustments on the self-centering "deluxe" joysticks Tandy offered for the CoCo back in the day. This gives good sensitivity without much chance of leaving a joystick unadjustably off-center.

Show Me

I haven't made much progress on Fahrfall this week. But I did put together a little demo to go with this post. The demo just reads the joystick and sets flag bits for each direction and the button status. The display portion of the code reads the flags and paints a corresponding red box on the screen for each bit set in the flags. It isn't much, but it proves the point. :-)

Well, that's all for now! Stay tuned for more info about the CoCo and further progress reports on Fahrfall!

The CPU is one of the most powerful of its era. The hardware includes two 8-bit accumulators A and B, which can be concatenated together and referenced as the D register. A number of 16-bit accommodations in the instruction set make use of the D register, and it is convenient for data movement. The 6809 also includes a hardware multiply instruction, for when that operation is necessary. (Alas, there is no divide instruction!) Finally, the 6809 was specifically built for running position independent code. This gives it a wealth of branching and data indexing capabilities not present in most of its contemporaries.

The SAM (Synchronous Address Multiplexer) glues the rest of the system together. This device controls access to the DRAM in the system, and provides the refresh signals for the DRAM as well. The 6883 also does the address decoding for the rest of the base CoCo system, providing chip selects for the other on-board devices and a couple for the expansion slot as well. The 6883 also controls the clock, allowing for a choice between two different clock speeds. Finally, the SAM integrates with the VDG in order to enable the CPU and the VDG to share the DRAM without interfering with one another. This final feature also allows for some extra videos modes not available with the VDG alone.

The VDG (Video Display Generator) is, of course, what puts the graphics on the screen. The 6847 is a utilitarian chip, providing a modest variety of both text and graphics modes in a limited variety of colors. "Semi-graphics" modes are available as well, with more simultaneous colors but less flexibility. The modest feature list gets even more modest as one tries to take advantage of certain features -- higher resolutions are only available in either black-green or black-white combinations; the colorful graphics modes have to pick between two fixed four-color palettes; and the "semi-graphics" modes are very low resolution. Still, the device can produce credible displays for the era. Also, the SAM/VDG combination allows for some higher-resolution "semi-graphics" modes that are less of a compromise to use.

Two PIA (Peripheral Interface Adapter) chips round-out the set. Each PIA provides two 8-bit digital I/O ports, as well as two 1-bit inputs and two other 1-bit I/O signals. The PIAs are used to implement all of the other peripherals that are part of the CoCo, with the exception of the expansion port.

Other Peripherals

One of the most important devices remaining to be described is the 6-bit Digital to Analog Converter (DAC). The DAC is used to output audio to the television and to transmit data to the cassette recorder interface. It is also used in conjunction with an on-board comparator circuit to digitize values from the joysticks. The input to the DAC comes from one of the PIA ports.

A two-channel analog multiplexor is part of the CoCo. One side is used to select between three audio sources: the DAC; the cassette input; and the expansion port. The other side is used to select between the two joysticks and each of their axes. The joystick axes connect to the other input of the comparator mentioned above. The selection for the multiplexor channels is done via two of the 1-bit outputs from the PIAs.

Two PIA ports are used to scan the keyboard. The handful of remaining PIA bits are used to implement the cassette player input (including motor control!), the serial port (with the help of some level shifters), and a 1-bit sound option. A couple of the bits used for the keyboard scan are reused to also monitor the buttons on the joysticks. The remaining 1-bit inputs of the PIAs are used to enable interrupt generation from the VDG, the expansion port, and the serial port's Carrier Detect bit.

Is That All?

Well, this is running a bit long...I didn't even get to the expansion port! Hopefully I didn't lose anyone. I could probably go into more details, but anyone that really wants more details can probably find them on their own. I suppose that I just wanted to provide a feel for how much the guys that put the CoCo together did to make the most of what they had available.

Anyway, in upcoming posts I hope to discuss things like what video mode I am using for Fahrfall, how to generate music and sound effects on the CoCo, how to read joysticks, etc. Hopefully the background provided above makes those posts a bit more digestible.

Sunday, January 8, 2012

I took some time on Saturday to get some platforms onto the screen. This turned-out to be simpler than I thought. I started with just a single, full-width platform scrolling continuously from the bottom to the top and then repeating. From there I progressed to using the LFSR data to randomize the platform pattern -- I'll talk about that a bit below. Then I moved to having three independent platforms on the screen at a time. I was so pleased with myself that I posted a video!

LFSR Data Anomalies

The LFSR is working great for my (pseudo-)random numbers. But as I noted in the video, it was possible to get either empty platforms or full-width "sweeper" platforms. Today I played around with correcting that.

The platform data is simply a bitmask, with each bit representing a corresponding portion of a platform's span. I started checking for "all ones" values in order to prevent the "sweepers". A full-width platform would be impossible to pass, resulting in "Game Over". I played with it a bit, and settled on simply substituting a default platform data value for any "all ones" values I found.

The nature of an LFSR is such that you can't really get a completely zero value for the LFSR. But my LFSR is 16-bits wide, and my platform data is only 8-bits wide. At first I was taking only half of the LFSR value for my platform data, and half an LFSR can be zero. I even observed an empty platform scroll up the screen in "real life" -- I should be a tester! :-) Anyway, now I also check for an "all zeroes" value and substitute the default platform data value in that case as well.

Platform Distribution

The platform data was already as random as the LFSR could make it, but I wasn't totally happy with how the platforms were looking. It seemed like there would be runs of too many gaps between platforms, or not enough, or whatnot -- all that could just be my imagination too. Anyway, I decided to experiment a bit, particularly with XORing the LFSR data with...whatever. Anyway, I settled on XORing the two halves of the LFSR data together, then applying the tests for "all ones" and "all zeroes" as described above. I don't know for sure if this is any better than before, but it feels better in the seat of my pants!

Just A Little Swizzle...

I wasn't entirely happy with the way the scroll planes were moving. They had been moving upward one position every 2, 4, 8, or 16 frames, depending on the plane. The code for handling this was also looking a bit unwieldy as well, at least for the "every 16" case. So, I refactored...

I changed from the 2-4-8-16 factors to factors of 2-4-6-8. The introduction of the "every 6" case required an independent counter, since 6 isn't a power of 2 like the rest of them. Anyway, I think the results looks a bit better overall -- less jerky and more quick. It does seem to lose a bit of the feeling of depth, but I think it is still alright. Plus, the code seems a lot cleaner too.

More To Come

I did that scroll plane swizzle after shooting the video above, so I suppose you will have to wait a bit to see it. I imagine that the next progress report is just days away!

Also, I have a few topics that relate more to the background of the project rather than to the progress of the project itself. For the benefit of the technically curious among us, I want to provide a bit more information about the CoCo, what tools I'm using, etc. I'll try to meter them out, and continue to intersperse them with some progress reports.

Saturday, January 7, 2012

The inspiration for Fahrfall is a game called DOWNFALL. That is a cool name for a cool game! But this is a different game, and a different game needs a different name! Any name involving "Goes Down" is out for similar reasons -- see the Prologue entry of this blog if you need a reminder as to why.

Still, the premise of the game is falling. In fact, I originally used "falling" as a working title. But "falling" just didn't seem to have the right ring to it.

That Sure Is A Long Fall

I brainstormed for a while for a theme, and kept coming back to ideas about falling a long way. I started to settle on "farfall", which seemed like a reasonable choice. I Googled a bit, and found enough references to suggest that "farfall" has a certain lack of uniqueness. In any case, it just wasn't turning me on.

Meine Deutsche Ist Nicht Gut

At some point, it occured to me that "far" sounds a bit like the German "fahr". A vague memory from an old Volkswagen commercial suggested to me that "fahr" might relate to driving, and a hunch suggested to me that "fall" might have a similar meaning in German as it does in English. German is notorious for its compound words, so I thought this might be a way to make something with at least a tenuous connection to a reasonable meaning but that retains some uniqueness.

I Googled a bit for "fahrfall" and some likely(?) German variations like "fahrenfall", "fahrfallen", "fahrenfallen", etc. I ran into a few references, but nothing that seemed to have a consistent meaning -- it seemed like "fahrfall" might be used a bit like slang, with various links to roads, driving, running, falling, etc. I pinged some native Germans and they more-or-less agreed with my interpretation -- one called it a "Denglish" word, which I suppose is the German equivalent to "Spanglish". :-)

A Name Is Born

So, "Fahrfall" doesn't really mean anything. Yet, it invokes a relationship to "driving" and "falling" (and maybe a few other things). Since the premise of the game is to control (i.e. drive) a fall, the name seems appropriate to me.

Friday, January 6, 2012

I originally added the flame effect just to fill the middle space at the top of the screen, and to provide a visual reminder that you can't let the player scroll off the top. At first it was just a static, irregular image -- first all in red, then in a motley red and orange.

Flicker Or Flash?

I decided I wanted the flames to "flicker". So I added code in the game loop to use an XOR operation to flip the red bits to orange and vice versa. At first this was annoyingly fast, so I slowed it down a bit by skipping a set number of frames between each flip. The result was OK, but very regular -- more like a flash than a flicker. The colors seemed a bit wrong too.

In the news recently have been some reports of arson out in California. Obviously I feel terrible for the losses of those involved, but the news reports did give me some really good views of raging flames! I realized that I needed to add some yellow at the core of the flames, and that the flicker effect needed to be more random.

LFSR PRNG, EE-I-EE-I-O!

Games tend to need "random" numbers anyway for a variety of uses. I knew I would need some sort of (pseudo-)random number generator (PRNG) eventually, so I might as well implement one now. I decided that a linear feedback shift register (LFSR) would be a good way to go. An LFSR is relatively simple to implement, reasonably cheap to execute, and can provide convincingly "random" sequences of numbers.

I settled on a a 16-bit LFSR, since that size is reasonably convenient to handle with the 6809's resources. I used the maximal-length polynomial for 16-bit LFSRs from the table in the LFSR Wikipedia article. For a random seed I used the Extended Color BASIC TIMVAL variable, which is a free running software counter used by the CoCo's ROM for timing purposes. I sprinkled-in some assembly code with a few logic operations and I was all set! For now I am bumping the LFSR after every frame, but I reckon that I might have to hit it more often before this is all over.

Flame On!

Now armed with (pseudo-)random numbers, I could make the flames flicker more realistically. Instead of flipping colors on a regular basis, I now use the LFSR data to randomize the time between color flips. Using what I learned from the arson reports on the news, I added some yellow bits to the flame graphics and arranged the red and orange bits with the red on the outside parts and the orange in the middle. Finally, I made sure that the yellow bits and some of the orange bits were exempted from the flickering. So now the colors go from yellow/orange/red to yellow/orange and back on an irregular basis. The overall effect looks pretty good "live", although the video cameras I've tried so far don't seem to pick it up very well.

I've spent more time on these flames than I ever intended to spend. But, I do think they look pretty good. I'm not sure if it shows-up very well in the video, so you might just have to take my word for it. FWIW, I also changed the color selection algorithm for the scroll effects to something that is a bit cheaper to execute. Anyway, I'll include a video clip just to show where I'm at...an actual game is still to come!