What's a column?
Columns was Sega's early 90s response to Tetris. Although it spawned several sequels and spin-offs, I don't think it was as popular. Looking into QuickBASIC clones, there were about three Tetris clones for every Columns clone... some noteworthy examples are Autumn Springs' (very flickering) rendition in 640x480 SVGA (using Future.Lib) in 2001, "Columns from scratch" by Daniel Covolo in 2009, "GemTris" by Daniel Kalna in 1996, Jewel by William Yu also in 1996, and "Col" by Don in 1999...
Even though the two are constantly compared, and while both are what I often refer to as "stackers," Columns is closer to Connect-4 than Tetris. In short, columns of three blocks appear on top of a 6x13 grid and slowly fall to the bottom. Blocks can be shifted and the column can be moved left or right. The goal is to connect three or more blocks in a straight line (horizontal, vertical or diagonal.) There's also a magic column that may appear at random when starting from a high level (at least 5.) A magic column will remove all blocks identical to the one it lands on, usually triggering satisfying chain-reactions. Level increases every 50 jewels destroyed, the more jewels in a row, the higher the score. Chain-reactions obviously add up... it's pretty standard stuff. The game also has a "Flash Columns" mode, in which the player must destroy a designated jewel located at the bottom of a pile.
Cooking by the book
I began working on this game to take a custom mode Y library for a ride. I got tired of copy/pasting code and adjusting it to my needs, so I think writing a proper library would be the right course of action (the goal was to obtain a compromise between flexibility and speed while also shielding the user as much as possible from mode Y's intricacies.) The library definitely benefited from the exercise. The game... not so much. I now know that I desperately need a triple-buffering mode (currently the library uses 2 pages for flipping, 1 page for sprites, and 1 page solids - that's 128Kb of graphics FOR FREE!) If we ignore the library stuff, we still have a somewhat enjoyable puzzle game at the end of the day.
I used the Genesis (aka Mega Drive outside North America) version for reference. That particular version of the game only featured jewels while the Game Gear and Master System versions had more block types. I guess Sega dropped the fruits and dice for the 16-bit version because they looked out of place with the ancient Greece theme they were going for... I sort of wanted them back so I had to redraw them, along with touching up the existing sprites to account for the non-square pixel aspect ratio of 320x200.
The program uses palette shifting for various stuff (such as the background turning teal/blue to brown/sand, the "game over" flickering neon, and the flickering magic jewels.) In retrospect, I should have modified specific palette indices rather than shifting multiple entries, but I was still trying to figure out a way to handle palettes from within the library in a user-friendly way (I still am to be honest.) Even with all the color repeats, only half of the palette was used.
Hello darkness my old friend
I resigned myself not to attempt Sound Blaster support this time around, because I suspect it is the reason why most of my other programs won't run outside of DOSBox. I was recently gifted an 18 year old Windows XP machine, which also only support emulated DOS (without proper sound.) Obviously, leaving an inaccurate emulator to use another inaccurate emulator isn't going to help me solve those issues, so I decided to use PC Speakers instead (if you can't stomach Column's music translated to PC Speaker beeps, you can disabled it anytime.)
I never attempted to write a stacker before and I figured a few things as I went. I'm more of an action game kind-of-guy where every character can move any time. But games like Columns are more "turn-based:" first the player moves the column until it lands, then a new turn starts: the computer tests all possible streaks. If any happens, yet another turn starts: the computer destroys the requested blocks and pushes them down. Then we're back to the testing turn. If nothing happens, it's back to the player's turn...
Outside of that, I was also initially surprised to see the grid was 6 by 13... that's not the power of twos I'm used to. And then I understood: there are two invisible rows on top of the screen (so a column can be temporarily placed there) and another at the bottom (filled with invisible, unbreakable blocks for collision.) There are also two invisible columns to the left and the right, also filled with unbreakable blocks (also for collision.) So that's in fact a 8x16 grid...
I also wish I paid more attention to the way the column moved early on: in the original version the column may move one pixel at a time when it reaches a certain speed. I guess the half-grid vertical move is only a visual trick.
Structurally, the code isn't that great. The way graphics are loaded and used to compose screens is messy at best and allows little room for mods. It could be reorganized and rewritten, but I'm again going to blame the library for that one: it loads (mode 13) .BSV files and converts them on the fly for mode Y. It means that I didn't get to use custom file formats and my usual file system (a big archive and loose files.) Leaving file processing to the library is what I expected someone else to wish from such a library, but it's not what I'm looking for... I could probably allow an extra routine to load from a memory segment (in which case memory paragraphs should be reserved to store entire files before processing.) I don't know. The rules for the two game mods (original and flash) are also spread here and there. With better planning, the game loop should have been able to handle more game modes and even the two-player mode...
Throw it on the pile, Joe!
At least it works. Minimal system requirements should be around an Intel 80286 @10Mhz (Intel 80386 @33Mhz recommended) and a VGA card with 256Kb. It was tested under DOSBox (3000 cycles) and Windows XP (Intel Celeron 1.5Ghz) and worked as expected. All sources included.