
Sign up to save your podcasts
Or


Pixie Power. Dan’s MEGA65 Digest for April 2026.
The MEGA65’s Raster Rewrite Buffer allows programs to draw characters on top of other characters, with the option to treat certain pixels as transparent. This enables all manner of graphical effects and techniques involving layers. In the previous Digest, I was able to use the RRB to sketch the user interface of a military strategy game, with terrain, soldiers, vehicles, indicators, and user interface elements in a 20-by-12 grid of 16-color 16-by-16 tiles, all in overlapping layers. Each tile is drawn separately, so it’s easy to imagine that this game could move the game objects across the terrain, like moving pieces across the spaces of a board game.
In this Digest, we’ll look at more features of the Raster Rewrite Buffer that open up even more possibilities. Specifically, we’ll see how to position layered game objects not just in a tile grid, but in arbitrary pixel positions on the screen. This is similar to VIC-II hardware sprites, but managed entirely by the program manipulating the RRB. Graphics programmers sometimes call techniques like these “soft sprites” to distinguish them from sprite features built into the video chip. Years ago, the MEGA65 community proposed that we call them pixies.
The power of pixies, coming up after these project announcements!
Dark Reaper, by MirageBD.
Dark Reaper is a new game by long-time MEGA65 contributor Lars Verhoeff (MirageBD), with an impressive smoothly-animated 3D maze engine, textures and lighting that really show off the MEGA65’s dynamic range, and atmospheric music and sound. Collect keys, open doors, find secret passages, and above all: avoid the Reaper. The map is essential to finding your way around and not getting caught.
DOS/65, MEGA65 port by Stefan Eilers.
The original DOS/65 was a CP/M workalike for the 6502 processor, by Rich Leary in 1982. Stefan Eilers has ported it to the MEGA65. You can download it from Filehost. The filesystem is compatible with CP/M version 1.4 and later, though of course a 6502 computer cannot run 8080/Z80 programs.
Don’t miss Stefan’s documentation, and the Github repo.
MegaPC, an 8086 emulator by xlar54.
Extending his emulator series, xlar54 has published an 8086 PC emulator capable of running MS-DOS, with a monochrome display and two virtual floppy drives.
You’ll need a DOS boot disk. Popular DOS apps work, though not always at full speed. See the Github repo for more information.
MegaSweeper65, by Hanyic Róbert.
I have been illustrating the most recent Digest articles on RRB graphics with a sketch of a game I’ve been calling “Tactical Strike.” Several people have asked to see these demos in their full form, beyond the excerpts I’ve been including in the newsletter.
You’ll have to forgive the crudeness of this model, I haven’t had time to paint it or to build it to scale. But if you’re interested:
The tactical.d81 disk image includes several display demos written in BASIC 65, along with the Tactical Strike tileset (NCM characters and palette) as data files. Each demo sets up the 20 x 12 tile display in the same way, as described in the previous article.
DS-MEGA65 is a version of DISPLAY3 written in assembly language. None of these demos strictly depend on features of BASIC65—it’s all register and memory manipulation—though I do use commands like WPOKE and SETBIT to illustrate the register concepts. This assembly language version also simplifies the code by embedding the tileset data directly in the program. Instead of loading the tileset into bank 4 from disk, I just tell the assembler to include it with the program at address $2800 in bank 0, and refer to those addresses in screen memory directly.
Someone asked me if a program running in GO64 mode could use these features. It sure can! You just need to switch the VIC from VIC-II compatibility mode into VIC-IV mode, like so:
The only other difference between d3-mega65.asm and d3-go64.asm is the start address, and the corresponding address in the BASIC bootstrap preamble. The rest of the code is identical. To try the GO64 version, just load and run it like any other program in GO64 mode.
So far, I’ve been drawing the tiles as they appear in the tileset. In the case of soldiers and vehicles, everyone is facing to the right. That’s not too bad given the board-game-like style of the display, but in the real game each team is going to start on opposite ends of the field and advance toward each other. Without changes, a soldier marching right to left will look like it is walking backwards towards the enemy team.
Of course, one possible solution is to have two tiles for each soldier, one facing to the left and one facing to the right. But the VIC-IV can help us out here. In the common case where we just want the same image flipped horizontally, we can just ask the VIC-IV to use the same graphic, and draw it flipped.
To draw any SEAM character flipped horizontally, set bit 6 of byte 0 of its color value.
Tactical Strike tiles are one NCM character across (16 pixels) and two characters tall (8 x 2 = 16 pixels). To flip the tile horizontally, Tactical Strike sets bit 6 of byte 0 of the color value for both characters.
Unsurprisingly, the VIC-IV can also flip a SEAM character vertically. To do so, set bit 7 of byte 0 of its color value.
If Tactical Strike had a use for flipping a tile vertically—and perhaps it doesn’t given the style of the game, but let’s just consider—notice that a tile is two NCM characters stacked vertically. To flip the full tile vertically, it would need to set bit 7 of byte 0 of the color value of both characters, and it would have to swap the characters themselves, so the bottom character is on top and vice versa.
Here’s a trivial example of drawing a left-facing red soldier at a pre-calculated screen location:
Here’s a brief review of where these numbers come from:
See DISPLAY7 on the disk. What changes would you make to flip the soldier upside down?
Tactical Strike uses the Raster Rewrite Buffer to draw game objects onto the terrain. To do this, it populates the beginning of a row of screen memory with terrain characters, then uses a GOTOX instruction to reset the draw position to the game object’s X position. This instruction is followed by the character for the game object itself, which is drawn on top of the terrain at the new X position.
I wrote my tile drawing routine to keep all tiles arranged in a 20 x 12 grid. For example, to draw a red soldier in the fifth column on a row, the routine could use a GOTOX instruction to set the draw position at X = (5 - 1) * 16 = 48, the pixel coordinate of the left-hand edge of the fifth column.
When the player moves the soldier, I want to animate the soldier marching across the field. I could just have him clomp across the grid locations, leaping 16 pixels at a time. That has a nice retro feel to it, but it’s not the only option. GOTOX takes a pixel coordinate, not a grid coordinate, so I could slide the soldier left or right by changing the GOTOX value a small number of pixels per animation frame.
For example, I could slide a soldier from one tile column to the next by one pixel per frame over 16 frames. In NTSC video mode at 60 frames per second, that would take 16/60 = 0.26 seconds. In PAL video mode at 50 frames per second, that’s 16/50 = 0.32 seconds.
See DISPLAY8, which animates a patrolling soldier, including horizontal flip.
Last month, we discussed several different strategies for using GOTOX to draw layers, including drawing full layers with “GOTOX = 0” instructions between them. Notice that to animate individual game objects, each object needs its own GOTOX instruction: each row starts with a full screen-width of terrain, followed by a “draw list” of graphics objects, each object using one GOTOX instruction to set its position followed by the graphics character (or characters) for the object. This provides enough flexibility to locate each object independently from other objects on the row, at the expense of some screen memory.
This is the general idea behind pixies. The program draws the background layer (or layers) into screen and color memory, one row at a time, followed by GOTOX instructions and characters for each pixie that appears on the row. Pixies can overlap, and must appear in screen memory in their desired order, from back to front. The VIC draws the entire row—background and pixies—by reading each row of screen memory from left (lowest memory address) to right (highest memory address), following all of the “draw a character” and “GOTOX” instructions in the order they appear.
Positioning pixies at arbitrary horizontal positions is pretty straightforward: just give the GOTOX instruction the desired pixel coordinate to start drawing the next character. The VIC draws the full width of the character from the left edge to the right edge, potentially drawing it across what we normally think of as two character columns—or tile grid columns in the case of Tactical Strike.
You can also use the Raster Rewrite Buffer to position pixies at arbitrary vertical locations. This takes a bit more effort. We want something similar to horizontal positioning, where a character is drawn across two character rows, with some of the character on one row and the rest of the character on the next row. But the VIC draws one row at a time, and can’t leave the current row to go draw somewhere else on the screen. It needs our help to understand how much of a given character to draw on a given row, and where to start drawing it. The mechanism for this is unusual, but it’s designed in a way that’s useful for common graphical effects.
Let’s consider an example in detail. Say we want to draw the red soldier such that its upper-left corner is at pixel coordinate X=0, Y=3. The soldier tile is 16 pixels tall, using two 16-by-8 NCM characters in the character set. To appear at vertical position Y=3, these two characters have to be drawn across three character rows:
The Raster Rewrite Buffer provides two separate features to make this possible.
Normally, when the VIC draws a character on a character row, it reads the first pixel row of that character’s pixel data and draws it on the first vertical pixel position of the character row, then the second for the second, and so on. For FCM/NCM characters, it gets the address of the first pixel row of the character by taking the screen code and multiplying by $40, and reads eight bytes of character set data for each pixel row.
You can tell the VIC to start reading character data on a different pixel row by setting a character data Y offset. An offset of +1 would tell the VIC to start reading the character data one row later: use the second pixel row of the character data for the first vertical pixel position, then use the third row of the character in the second position, and so on. This effectively shifts the character up by one pixel, cutting off the top. When the VIC gets to the eighth position, the +1 offset tells it to read the first pixel row of the next character in the character set.
One way to think about this is to imagine the entire character set stacked vertically. When the VIC draws an FCM/NCM character, it uses the screen code times $40, plus the character data Y offset times 8, as the address of the first pixel row. You can use the screen code and the offset to position an 8-pixel-high window anywhere in the character set stack, and the contents of this little window are drawn into the character row. The offset can be in the range -7 to +7.
To draw the red soldier at vertical position Y=3, we use a character data Y offset of -3 for all three rows. Each character row works as follows:
Tada! The red soldier now appears at pixel coordinate Y=3! That’s what we wanted, right?
OK, rows 1 and 3 don’t look quite right yet. They’re stealing pixel rows from adjacent characters in the character set to fill out the set of eight. We need another feature to tell the VIC to not draw anything on those pixel rows.
You can tell the VIC to skip drawing specific pixel rows by setting a row mask. This mask can enable or disable any of the eight pixel rows being drawn to the current character row. Combined with the character data Y offset, this completes our solution for drawing pixies at arbitrary vertical positions, like so:
In other words, all masked rows appear as transparent, and we can omit the neighboring pixels from the result of offsetting the character set data.
The character data Y offset and the row mask are part of the GOTOX instruction. This has two implications: they are set independently of the characters, and they apply to all subsequent characters on the character row, until they are changed by another GOTOX instruction, or they are reset at the end of the row.
You set the Y offset using bits 4 through 7 of the GOTOX instruction’s screen memory byte 1. Bit 4 is the sign bit: set it for a negative offset, or clear it for a non-negative offset. Bits 5-7 are the value 0 through 7.
To enable the row mask, set the GOTOX instruction’s bit 3 of color memory byte 0. Then set the row mask using all eight bits of color memory byte 1. Each bit of the row mask corresponds to a pixel row, where bit 0 is the top-most row, bit 1 is the second row, and so on. Set the row mask bit to show the row.
Here’s the complete picture for drawing the red soldier at pixel coordinates X=0, Y=3. In this example, each row has 40 bytes for the background, 2 bytes for a GOTOX instruction, and another 42 bytes for whatever else is needed on the row. The o variable is the screen memory offset for that row’s GOTOX instruction. The soldier characters follow the GOTOX instructions on each row.
Just to be sure, let’s walk through row 0:
Try working out the other rows.
See DISPLAY9 on the disk. Try enabling and disabling the row mask to see the difference. Note that Xemu cuts off the top row in this example; see notes near the end of the last Digest.
The Y offset feature worked out nicely for Tactical Strike. Each 16-by-16 tile is two NCM characters arranged vertically, and the two characters for each tile appear next to each other in the character set. When setting the -3 offset for row 2 in our example, we got exactly what we wanted: three rows from the top character and five rows from the bottom character.
This suggests a general rule for organizing character sets for large pixies: top to bottom, left to right. This makes it easier to use unmasked offset characters for the interior rows, taking advantage of the VIC’s ability to read rows from adjacent characters, as part of pixie vertical positioning.
It may not look like it yet, but we now know enough VIC-IV graphics features to implement Amiga-quality games! Super Extended Attribute Mode gives us full-color characters with a 256-color palette of 23-bit color. The Raster Rewrite Buffer lets us draw character graphics in layers with transparency, at arbitrary pixel locations. We can use these techniques to implement “pixies,” and draw a large number of them to the screen, on top of detailed backgrounds. A given object can be multiple characters wide and tall, and we can include multiple frames of animation in our character set and switch between them just by changing screen codes.
Knowing how it works and getting it to work are two different things. While we now know which VIC-IV features can be used to implement pixies with GOTOX instructions across multiple rows of characters, this isn’t how we want to think about pixies in our game code. I just want to be able to say that a game object uses a particular frame of animation from my tileset, and appears at a given set of pixel coordinates. It’d be best if some general purpose library could manage the screen and color memory, character codes and GOTOX instructions, Y offsets and row masks.
RetroCogs, the implementor of the MEGA65 port of RogueCraft DX, is developing GameShell65, an assembly language framework with abstractions for pixies and other graphics techniques based on the RRB. It’s in early stages, but there’s plenty of code to learn from and re-use. Even if you don’t plan to use it, check out the pixie documentation for hints on how to implement a workable pixie system.
Several of the demos on the TACTICAL.D81 disk use a BASIC subroutine to do the heavy lifting for drawing tiles in layers. It might be possible to encapsulate pixie positioning logic in that routine as well, depending on what kind of animations and movement I want the game to have. Whether it’s fast enough to do in BASIC, or if assembly language is needed, also depends on the game.
Of course, there’s still more to discuss about character graphics. There are several character rendering features we still haven’t yet covered. Fast-paced games typically use Direct Memory Access features to manage screen and color memory. And there’s more to say about full-screen scrolling and other special effects. These will have to wait for future Digests!
If you want to see more articles like these, consider supporting the Digest. Visit ko-fi.com/dddaaannn for more info.
See you next month!
— Dan
By Dan SandersonPixie Power. Dan’s MEGA65 Digest for April 2026.
The MEGA65’s Raster Rewrite Buffer allows programs to draw characters on top of other characters, with the option to treat certain pixels as transparent. This enables all manner of graphical effects and techniques involving layers. In the previous Digest, I was able to use the RRB to sketch the user interface of a military strategy game, with terrain, soldiers, vehicles, indicators, and user interface elements in a 20-by-12 grid of 16-color 16-by-16 tiles, all in overlapping layers. Each tile is drawn separately, so it’s easy to imagine that this game could move the game objects across the terrain, like moving pieces across the spaces of a board game.
In this Digest, we’ll look at more features of the Raster Rewrite Buffer that open up even more possibilities. Specifically, we’ll see how to position layered game objects not just in a tile grid, but in arbitrary pixel positions on the screen. This is similar to VIC-II hardware sprites, but managed entirely by the program manipulating the RRB. Graphics programmers sometimes call techniques like these “soft sprites” to distinguish them from sprite features built into the video chip. Years ago, the MEGA65 community proposed that we call them pixies.
The power of pixies, coming up after these project announcements!
Dark Reaper, by MirageBD.
Dark Reaper is a new game by long-time MEGA65 contributor Lars Verhoeff (MirageBD), with an impressive smoothly-animated 3D maze engine, textures and lighting that really show off the MEGA65’s dynamic range, and atmospheric music and sound. Collect keys, open doors, find secret passages, and above all: avoid the Reaper. The map is essential to finding your way around and not getting caught.
DOS/65, MEGA65 port by Stefan Eilers.
The original DOS/65 was a CP/M workalike for the 6502 processor, by Rich Leary in 1982. Stefan Eilers has ported it to the MEGA65. You can download it from Filehost. The filesystem is compatible with CP/M version 1.4 and later, though of course a 6502 computer cannot run 8080/Z80 programs.
Don’t miss Stefan’s documentation, and the Github repo.
MegaPC, an 8086 emulator by xlar54.
Extending his emulator series, xlar54 has published an 8086 PC emulator capable of running MS-DOS, with a monochrome display and two virtual floppy drives.
You’ll need a DOS boot disk. Popular DOS apps work, though not always at full speed. See the Github repo for more information.
MegaSweeper65, by Hanyic Róbert.
I have been illustrating the most recent Digest articles on RRB graphics with a sketch of a game I’ve been calling “Tactical Strike.” Several people have asked to see these demos in their full form, beyond the excerpts I’ve been including in the newsletter.
You’ll have to forgive the crudeness of this model, I haven’t had time to paint it or to build it to scale. But if you’re interested:
The tactical.d81 disk image includes several display demos written in BASIC 65, along with the Tactical Strike tileset (NCM characters and palette) as data files. Each demo sets up the 20 x 12 tile display in the same way, as described in the previous article.
DS-MEGA65 is a version of DISPLAY3 written in assembly language. None of these demos strictly depend on features of BASIC65—it’s all register and memory manipulation—though I do use commands like WPOKE and SETBIT to illustrate the register concepts. This assembly language version also simplifies the code by embedding the tileset data directly in the program. Instead of loading the tileset into bank 4 from disk, I just tell the assembler to include it with the program at address $2800 in bank 0, and refer to those addresses in screen memory directly.
Someone asked me if a program running in GO64 mode could use these features. It sure can! You just need to switch the VIC from VIC-II compatibility mode into VIC-IV mode, like so:
The only other difference between d3-mega65.asm and d3-go64.asm is the start address, and the corresponding address in the BASIC bootstrap preamble. The rest of the code is identical. To try the GO64 version, just load and run it like any other program in GO64 mode.
So far, I’ve been drawing the tiles as they appear in the tileset. In the case of soldiers and vehicles, everyone is facing to the right. That’s not too bad given the board-game-like style of the display, but in the real game each team is going to start on opposite ends of the field and advance toward each other. Without changes, a soldier marching right to left will look like it is walking backwards towards the enemy team.
Of course, one possible solution is to have two tiles for each soldier, one facing to the left and one facing to the right. But the VIC-IV can help us out here. In the common case where we just want the same image flipped horizontally, we can just ask the VIC-IV to use the same graphic, and draw it flipped.
To draw any SEAM character flipped horizontally, set bit 6 of byte 0 of its color value.
Tactical Strike tiles are one NCM character across (16 pixels) and two characters tall (8 x 2 = 16 pixels). To flip the tile horizontally, Tactical Strike sets bit 6 of byte 0 of the color value for both characters.
Unsurprisingly, the VIC-IV can also flip a SEAM character vertically. To do so, set bit 7 of byte 0 of its color value.
If Tactical Strike had a use for flipping a tile vertically—and perhaps it doesn’t given the style of the game, but let’s just consider—notice that a tile is two NCM characters stacked vertically. To flip the full tile vertically, it would need to set bit 7 of byte 0 of the color value of both characters, and it would have to swap the characters themselves, so the bottom character is on top and vice versa.
Here’s a trivial example of drawing a left-facing red soldier at a pre-calculated screen location:
Here’s a brief review of where these numbers come from:
See DISPLAY7 on the disk. What changes would you make to flip the soldier upside down?
Tactical Strike uses the Raster Rewrite Buffer to draw game objects onto the terrain. To do this, it populates the beginning of a row of screen memory with terrain characters, then uses a GOTOX instruction to reset the draw position to the game object’s X position. This instruction is followed by the character for the game object itself, which is drawn on top of the terrain at the new X position.
I wrote my tile drawing routine to keep all tiles arranged in a 20 x 12 grid. For example, to draw a red soldier in the fifth column on a row, the routine could use a GOTOX instruction to set the draw position at X = (5 - 1) * 16 = 48, the pixel coordinate of the left-hand edge of the fifth column.
When the player moves the soldier, I want to animate the soldier marching across the field. I could just have him clomp across the grid locations, leaping 16 pixels at a time. That has a nice retro feel to it, but it’s not the only option. GOTOX takes a pixel coordinate, not a grid coordinate, so I could slide the soldier left or right by changing the GOTOX value a small number of pixels per animation frame.
For example, I could slide a soldier from one tile column to the next by one pixel per frame over 16 frames. In NTSC video mode at 60 frames per second, that would take 16/60 = 0.26 seconds. In PAL video mode at 50 frames per second, that’s 16/50 = 0.32 seconds.
See DISPLAY8, which animates a patrolling soldier, including horizontal flip.
Last month, we discussed several different strategies for using GOTOX to draw layers, including drawing full layers with “GOTOX = 0” instructions between them. Notice that to animate individual game objects, each object needs its own GOTOX instruction: each row starts with a full screen-width of terrain, followed by a “draw list” of graphics objects, each object using one GOTOX instruction to set its position followed by the graphics character (or characters) for the object. This provides enough flexibility to locate each object independently from other objects on the row, at the expense of some screen memory.
This is the general idea behind pixies. The program draws the background layer (or layers) into screen and color memory, one row at a time, followed by GOTOX instructions and characters for each pixie that appears on the row. Pixies can overlap, and must appear in screen memory in their desired order, from back to front. The VIC draws the entire row—background and pixies—by reading each row of screen memory from left (lowest memory address) to right (highest memory address), following all of the “draw a character” and “GOTOX” instructions in the order they appear.
Positioning pixies at arbitrary horizontal positions is pretty straightforward: just give the GOTOX instruction the desired pixel coordinate to start drawing the next character. The VIC draws the full width of the character from the left edge to the right edge, potentially drawing it across what we normally think of as two character columns—or tile grid columns in the case of Tactical Strike.
You can also use the Raster Rewrite Buffer to position pixies at arbitrary vertical locations. This takes a bit more effort. We want something similar to horizontal positioning, where a character is drawn across two character rows, with some of the character on one row and the rest of the character on the next row. But the VIC draws one row at a time, and can’t leave the current row to go draw somewhere else on the screen. It needs our help to understand how much of a given character to draw on a given row, and where to start drawing it. The mechanism for this is unusual, but it’s designed in a way that’s useful for common graphical effects.
Let’s consider an example in detail. Say we want to draw the red soldier such that its upper-left corner is at pixel coordinate X=0, Y=3. The soldier tile is 16 pixels tall, using two 16-by-8 NCM characters in the character set. To appear at vertical position Y=3, these two characters have to be drawn across three character rows:
The Raster Rewrite Buffer provides two separate features to make this possible.
Normally, when the VIC draws a character on a character row, it reads the first pixel row of that character’s pixel data and draws it on the first vertical pixel position of the character row, then the second for the second, and so on. For FCM/NCM characters, it gets the address of the first pixel row of the character by taking the screen code and multiplying by $40, and reads eight bytes of character set data for each pixel row.
You can tell the VIC to start reading character data on a different pixel row by setting a character data Y offset. An offset of +1 would tell the VIC to start reading the character data one row later: use the second pixel row of the character data for the first vertical pixel position, then use the third row of the character in the second position, and so on. This effectively shifts the character up by one pixel, cutting off the top. When the VIC gets to the eighth position, the +1 offset tells it to read the first pixel row of the next character in the character set.
One way to think about this is to imagine the entire character set stacked vertically. When the VIC draws an FCM/NCM character, it uses the screen code times $40, plus the character data Y offset times 8, as the address of the first pixel row. You can use the screen code and the offset to position an 8-pixel-high window anywhere in the character set stack, and the contents of this little window are drawn into the character row. The offset can be in the range -7 to +7.
To draw the red soldier at vertical position Y=3, we use a character data Y offset of -3 for all three rows. Each character row works as follows:
Tada! The red soldier now appears at pixel coordinate Y=3! That’s what we wanted, right?
OK, rows 1 and 3 don’t look quite right yet. They’re stealing pixel rows from adjacent characters in the character set to fill out the set of eight. We need another feature to tell the VIC to not draw anything on those pixel rows.
You can tell the VIC to skip drawing specific pixel rows by setting a row mask. This mask can enable or disable any of the eight pixel rows being drawn to the current character row. Combined with the character data Y offset, this completes our solution for drawing pixies at arbitrary vertical positions, like so:
In other words, all masked rows appear as transparent, and we can omit the neighboring pixels from the result of offsetting the character set data.
The character data Y offset and the row mask are part of the GOTOX instruction. This has two implications: they are set independently of the characters, and they apply to all subsequent characters on the character row, until they are changed by another GOTOX instruction, or they are reset at the end of the row.
You set the Y offset using bits 4 through 7 of the GOTOX instruction’s screen memory byte 1. Bit 4 is the sign bit: set it for a negative offset, or clear it for a non-negative offset. Bits 5-7 are the value 0 through 7.
To enable the row mask, set the GOTOX instruction’s bit 3 of color memory byte 0. Then set the row mask using all eight bits of color memory byte 1. Each bit of the row mask corresponds to a pixel row, where bit 0 is the top-most row, bit 1 is the second row, and so on. Set the row mask bit to show the row.
Here’s the complete picture for drawing the red soldier at pixel coordinates X=0, Y=3. In this example, each row has 40 bytes for the background, 2 bytes for a GOTOX instruction, and another 42 bytes for whatever else is needed on the row. The o variable is the screen memory offset for that row’s GOTOX instruction. The soldier characters follow the GOTOX instructions on each row.
Just to be sure, let’s walk through row 0:
Try working out the other rows.
See DISPLAY9 on the disk. Try enabling and disabling the row mask to see the difference. Note that Xemu cuts off the top row in this example; see notes near the end of the last Digest.
The Y offset feature worked out nicely for Tactical Strike. Each 16-by-16 tile is two NCM characters arranged vertically, and the two characters for each tile appear next to each other in the character set. When setting the -3 offset for row 2 in our example, we got exactly what we wanted: three rows from the top character and five rows from the bottom character.
This suggests a general rule for organizing character sets for large pixies: top to bottom, left to right. This makes it easier to use unmasked offset characters for the interior rows, taking advantage of the VIC’s ability to read rows from adjacent characters, as part of pixie vertical positioning.
It may not look like it yet, but we now know enough VIC-IV graphics features to implement Amiga-quality games! Super Extended Attribute Mode gives us full-color characters with a 256-color palette of 23-bit color. The Raster Rewrite Buffer lets us draw character graphics in layers with transparency, at arbitrary pixel locations. We can use these techniques to implement “pixies,” and draw a large number of them to the screen, on top of detailed backgrounds. A given object can be multiple characters wide and tall, and we can include multiple frames of animation in our character set and switch between them just by changing screen codes.
Knowing how it works and getting it to work are two different things. While we now know which VIC-IV features can be used to implement pixies with GOTOX instructions across multiple rows of characters, this isn’t how we want to think about pixies in our game code. I just want to be able to say that a game object uses a particular frame of animation from my tileset, and appears at a given set of pixel coordinates. It’d be best if some general purpose library could manage the screen and color memory, character codes and GOTOX instructions, Y offsets and row masks.
RetroCogs, the implementor of the MEGA65 port of RogueCraft DX, is developing GameShell65, an assembly language framework with abstractions for pixies and other graphics techniques based on the RRB. It’s in early stages, but there’s plenty of code to learn from and re-use. Even if you don’t plan to use it, check out the pixie documentation for hints on how to implement a workable pixie system.
Several of the demos on the TACTICAL.D81 disk use a BASIC subroutine to do the heavy lifting for drawing tiles in layers. It might be possible to encapsulate pixie positioning logic in that routine as well, depending on what kind of animations and movement I want the game to have. Whether it’s fast enough to do in BASIC, or if assembly language is needed, also depends on the game.
Of course, there’s still more to discuss about character graphics. There are several character rendering features we still haven’t yet covered. Fast-paced games typically use Direct Memory Access features to manage screen and color memory. And there’s more to say about full-screen scrolling and other special effects. These will have to wait for future Digests!
If you want to see more articles like these, consider supporting the Digest. Visit ko-fi.com/dddaaannn for more info.
See you next month!
— Dan