Edutris

A while back, I wrote a Columns clone to test a custom graphic library. As the code got larger and more complex, I realized that the library was desperately missing some pieces. So I went back to the drawing board and added a few much-needed features. Now, there are still some bits and pieces missing, but it's an obvious improvement over the initial effort. So I had to test it out...

Long story short

Remember that bitwise operator tutorial masquerading as a "build your own Tetris" article? It contained a lot of text, some illustrations, and even a very barebones game if you stitched the code snippets together. Well, I returned to it and wrote a Tetris clone. Now, QuickBASIC certainly doesn't NEED yet another Tetris clone (I got maybe thirty of those in my collection) but it was a good way for me test the new version of the graphic library.

The source code for both the game and the library are available in the download and they are both heavily commented... but that's not all: the game was also designed with modding in mind. The resource system allows the replacement (or addition) of background images, custom blocks, music, and even the layout (where interface elements are placed on the screen.)

Ch-ch-ch-ch-changes

One of the big changes in the graphic library is how images are stored. Quick reminder: Mode-Y has 4 pages of video memory, with a resolution of 320x200 each. Because four pixels share the same address, each page is 16,000 offsets (or 1,000 paragraphs) apart.

Like before, pages 0 and 2 are used for double-buffering: we display the front page while we draw on the back page, then when the frame is rendered, flip the front and back pages. Pages 1, because it is sitting between pages 0 and 2, is used for graphics that MUST be processed one pixel at a time, such as sprites (since we're moving data from page 1 to page 0 or 2, the distance in offsets is never greater than 32,000 -- meaning we can use DEF SEG, PEEK, and POKE, without fear of overflowing signed 16-bit integers.) Graphics that cannot easily be accessed with signed integers (but can be copied in bulk) are processed with QuickBASIC's B$ASSN, a compiler routine used to move string data, and stored on the 3rd page.

The previous version of the library made a strict distinction between sprites and solids, and forced sprites into page 1, and solids into page 3, meaning that we could only ever have up to 64Kb of either type (the image handle would also reflect the type of image as sprites would be handle 0 to 255, and solids 256 to 511.) Now, the library always store sprites on page 1, and solids on page 2 -- unless page 2 is maxed out, in which case it may be stored on page 1. This means that we can have up to 64Kb of sprites, and between 64Kb and 128Kb of solids, depending on the memory available in either page. Also, handles are sequential, regardless of the image type (they are numbered 0 to 511.)

The previous change now allows page 3 to be reserved for triple-buffering: by reserving a huge 320x200 solid image as soon as possible, we can now clear the back page with the content of page 3, the same way we would repeat the front page (visible) to the back page (working.)

Another big change was made to graphic files processing. In the previous version, the library would handle BSV files on its own, converting scanlines from linear to planar, and store the content in video RAM. The new version of the library doesn't handle files (except for screenshots) and leaves the decoding up to the main program. It can then upload entire scanlines (in either planar or linear format) to a reserved image. The data can also be downloaded if needed.

A memory deallocation bug has been fixed too: in an absolutely baffling move, I was invoking the wrong interrupt routine. The value in the comment (0x48) didn't match the one in the code (0xA9,) which doesn't really matter as both were incorrect (it was actually 0x49.) Don't ask how I screwed things up that bad, I don't know either.

The library also features a bunch of primitive drawing routines (lines, rectangles, boxes, and points,) the ability to capture some of the working frame into an image (like GET in QuickBASIC) and a customizable viewport (which automatically discards pixels written outside the specified rectangular area.)

All in all, it's much better.

Thank you, Mike, very cool!

The minimal system requirements are especially low (a 80286 at 8Mhz should be enough,) and (of course,) a VGA card with 256Kb of memory. The game supports keyboard (with customizable controls) and gamepad. Check it out!