The work continues… I absolutely intend for this game to be finished and complete in 2018. It’s amazing how many different pieces and parts need to be completed though to make that happen.
Right now, I’m working on something I’ve been doing off and on since the start of the project, the opening title screen (with music) and the interface for creating new games. The code has never been written so it’s a new fresh thing to do, and it’s helping me sort out which functions need to be in the “root” module.
The title screen however, I’ve had a prototype of that for awhile. First some background…
The TI-99/4a’s video chip is the TMS9918A, released in 1979. The “4A” part of the computer’s name comes from the fact it has the appended version of the original chip, which added “bitmap mode” to the TI. After studying it and working with it for some time, I have to say it was probably one of the best chips on the market until the Commodore VIC-II came out. And even then, it was still competitive; if the TI had possessed the same level of 3rd party software development as the Commodore you’d have seen some pretty impressive games on it.
This same chip was also used in the MSX computer systems that were in widespread use outside the US in the early and mid 1980’s. MSX games actually look a lot like classic Nintendo games; I suspect that many of the same developers went on to write NES games and used similar software techniques to maximize the hardware.
The MSX2 platform had a successor chip, developed by Yamaha based on TI’s original schematics, called the 9938 (and later 9958), which offered 80-column resolution and much greater sprite and color support. Adding a 9938 or 58 to the TI was a good way to get an 80-column mode.
So bitmap mode on the 9918A was meant to give the TI the ability to do “turtle graphics” like most of the other platforms of the day, which could freely draw all over the screen. And so it does… but with some critical differences in implementation.
Most other computers approached high-resolution video as follows:
- Determine a color depth in bits. (Usually 1 to 2 bits, for 2 or 4 colors)
- Create a video buffer in CPU memory of the requisite size. (A 256×192 screen would require 6K. Double that for 4 colors.)
- Render the screen by processing left to right, up to down all the pixel data in the buffer synchronously
Most 8-bit computers didn’t have enough CPU cycles to render the screen with a lot of colors, so some would double the pixel width to gain more colors, creating an odd hybrid look. This was typically referred to as “artifact” colors, this effect can be seen on the Atari 8-bit home computers, Tandy Color Computer and Apple II. (Wozniak, being a brilliant engineer, also figured out a way to get six artifact colors not just four, among other optimizations.)
TI took a different approach. They extended the existing “graphics mode” which used an extended 256-character ASCII table by adding two more tables so you could fill up the entire screen with 768 patterns. Then they expanded the color table to match it in size, so you could define a foreground and background color for every row of 8 pixels. Some mathematics are required to calculate pixel location, since it wasn’t a continuous buffer, but this allowed you to have complete control of the screen to the pixel.
This approach has some advantages. Unlike every other computer, the TI can have ALL colors on the screen at all times. And with a cell-based architecture, things like scrolling are a lot easier to do, albeit at the cell level, not the pixel level.
Of course, there are trade-offs. Only having two colors for every eight pixels requires some artistic planning to prevent “jagged” effects. This is somewhat mitigated by the fact the TI doesn’t render color differential all that well in NTSC. An example: If you place two single pixels of two different colors next to each other, unless they are VERY different in brightness and tint, you won’t be able to discern them. Two pixels of the same color next to each other, though, stand out much better.
A far worse problem is that the 9918A has it’s own memory separate from the CPU. Changes to it are done through a memory mapped port, which means the CPU has to spend cycles moving data back and forth. On paper, using 16-bit memory for registers and ONLY registers for the move, you could theoretically pass data fast enough to update the 6K pattern table at a 30/second frame rate, but in practice it doesn’t work. Games such as the Red Baron Flight simulator get around this by only doing partial updates.
Also, the VDP chip only had 16K of RAM, and you’re using nearly 80% of it just to render the screen. Add in a sprite pattern table (another 2K) and you’re pretty much out of memory with no room for buffer space. This can be problematic if you want to use disk file systems; they require at least a kilobyte at the top of RAM to operate.
Finally, by separating color from pattern, it makes color and pattern changes difficult to do at the same time. Other computers had to create sprites in software by storing pixel patterns and finding ways to “blit”, or “bit block transfer” graphics over top each other to create a seamless sense of movement. The TI can do this, but not very well as you have to move stuff at least 8 pixels at a time horizontally to prevent color corruption, and two writes to two different areas of memory may lead to a “jumpy” look with color lagging behind the pattern change.
For the CRPG, I’m using bitmap mode, but a hybrid form of it. You can configure the VDP registers to mask out the extra color and pattern tables and get an “enhanced graphics mode” that gives you the color depth of bitmap mode but only in a single table. There is a small trade-off with sprites; they are dependent upon the pattern table register for some calculations and the bitmask throws them off so you only can really use 8 instead of 32, but it’s an acceptable limit.
For the title screen though, I’m using full bitmap to make a beautiful scene, based on a painting by Thomas Moran. The only problem I had was, how to draw it?
Most of the graphics programs on the TI have the same fundamental problem, they’re trying to apply a pattern that doesn’t fit the TI’s architecture. Drawing lines and circles is not the way to make a good looking title screen. Most of them fail to expose the true nature of bitmap mode as well, neither telling you about the color limitation or giving direct control of foreground and background color. (Paint N’Print is probably the most usable in this regard, but it alternates foreground/background with no indication of which you’ve changed.)
There’s a couple of modern tools you could use for this work.
Magellan is designed to let you edit character sets and draw maps, but it doesn’t have bitmap-friendly tools. (extend to three tables, plot all characters automatically to make a drawing grid, etc.)
Convert9918 is a well-designed tool to convert any existing image to 9918A format. It has a wide variety of different algorithms to color match and render images. In practice, though, I haven’t found settings to get the effect and appearance I want. In particular, details get lost and you get some weird color choices at times.
So how am I doing it? I wrote my own bitmap editing tool. Since I’m only really working at a pixel level, it doesn’t need to BE in bitmap mode all the time, just have a memory buffer of data I can edit on screen and then occasionally view to make sure it looks good. Using a paint program I drew a lattice of grid lines on the image I want so I can approximate things and decide which objects I want to stand out and which ones I want to mask.
So that’s what I’m doing… it’s slow-going, but very satisfying because as an artist I have control over how it looks. And I think I can make something very cool. 🙂
Great article and informative, since I’m comletely unfamiliar with the specs of the TI 99 graphics chip. At the end of the day, any retro gaming dev project is all about confining yourself or embracing the aesthetics and quirks of that platform’s graphics and aound hardware.
I think I posted this before, but for my own project, I am limiting myself to 4 floppy disk sides for the amount of space the game will take so that:
1) the game can run on the original hardware with memory expansion and a floppy disk drive. While it makes far more sense to play the game with an SD card reader (just to avoid disk swapping) it is still a retro title.
2) I definitely don’t want to produce more than 600KB of code and content because I would go insane if I had to do more. I just spend 2 weeks designing a city (and there will be 20 in total) that uses about 8KB of memory. It also took me over a month to design a 128*128 tile world map by hand. I probably should have used a world map ASCII tile generator, but at least I can claim that it is a human made one. At the end of the day, I am just one guy and so there are human limits to retrogaming projects even if we have all the modern amenities of cross platform development on a modern PC to help us.
Yeah, the amount of time to generate content is considerable… my first 25% wasn’t too bad, but that was mainly because I’ve had the outline of the places for awhile.
When I started to sketch out some of the materials for disk 2, I started to realize I hadn’t completely planned things out… And some things I’m not sure I want to keep. I definitely don’t want it feeling like the first part of the game is cohesive and strong and the last half rushed, weak, or repetitive…
I guess it all comes down to how much detail you want to put in. For the first few cities that I designed by hand, I had a lot of fun writing dialogue and coming up with ideas but now that I’ve finished 5 out of 20 of them, I’m already having brain farts coming up with things. I mean, how much original dialogue can you produce for the city guards, the town drunk, etc? But as I plug along, I’m finding myself coming up with creative ways to do just a little bit more with the game’s city engine with each new city that I design.
I find writing dialogue and text much more difficult than to do graphics and sound, at least from my vantage point. Richard Garriott made it seem all so easy to do when he did it back in the day. One definitely has to concede that he was a near genius.
I’ve been reading your posts for a while, starting from the very beginning, so I wanted to stop here for a while. I really enjoy this journey, and I need to admit that the title screen looks excellent so far, that’s a great piece of work. It’s so interesting how constraints might limit at first, but when carefully tamed with some patience and peacefulness, you can get really great results you originally wanted, or even create some fabulous effects you wouldn’t imagine.
Add me to the roll call of late discoverers of your quest. I found this last week and I’m reading from the beginning. I have a lot of comments but want to avoid cluttering really old posts with my thoughts and questions which might be answered later in the series.
I come from a C64/C128 background and I have found your process inspiring. First off, I love the details in this and other posts because while I’m a Commodore enthusiast and programmer I never knew or understood the architectures and limitations of other systems available at the same time. I’m learning a lot here, so thank you. And the process is really inspiring me to get back to my own vintage computer and start a similar project.
At first I read you wanted to do your game in Extended BASIC with some ASM routines. I couldn’t see how you could fit so much in using BASIC but everything you talked about writing was ASM so I guess the BASIC portion was abandoned early on (you never made that clear). I think 9918 ASM is much more powerful than 6502 ASM. Your code snippets are much shorter than I imagine I would write. One question I had was that given how limited memory is, why are you making everything into a single program? Surely aspects of the game aren’t always relevant and you could create more complex engines if you unloaded one engine to load the next one when you change to a new part of the game that had different needs. Like combat vs exploration. Overlays could give you effectively more space for game engine code.
Welcome! I’m glad you’re enjoying it and finding inspiration. 😀
I didn’t plan to write this CRPG in Extended BASIC, I actually always wanted it in 100% assembly. Another project of mine, Wizard’s Doom, is in XB with assembly routines to assist.
Yeah, the TMS9900 processor is pretty nice for coding. Because it’s 16-bit the instructions are 2 bytes, but you can get more done in less lines.
I actually do break the program apart into modules, but I load all of it into memory because it is much faster that way. On an actual TI using original hardware, trying to load memory segments from disk would take way too long to be effective. Before I switched to the SAMS system (which gave me 1024k of CPU memory verses 32k) I tried to offload data to disk and the performance was… Well, really bad. Nearly unplayable.
Yes, TMS9900 definitely has some advantages. Specifically I was noting that you have 1) more registers to play with, 2) 16b native arithmetic (although you seem to be more byte-oriented in ROA this would benefit so many programmers), and 3) native multiply and divide. I’ve written signed and unsigned 16b x 16b multiply using 8b assembly with only shift and add instructions. It’s a headache and very long with lots of calls to 16b add and 16b shift routines I had to write. You can write 1 instruction to get 16b x 16b multiply. I don’t even want to think about the division (although that’s on my plate for a non-gaming project I have in mind).
Yeah, the TMS9900 supports 16 general purpose registers.
You can also context-switch to another set of 16 registers anywhere in CPU memory; this is a huge fundamental difference between it and the Intel 8800 and CMOS 6502 designs.
Most of the time you want your registers in the only 16-bit true RAM in the system, a 256 byte “scratch pad”, but you can have them anywhere you can free up a 32 byte block.
This has the effect of slowing the TI down to comparable to a typical 8-bit machine of the same era, even with a 3mhz 16-bit processor.