mirror of https://github.com/pevans/erc-c.git
111 lines
3.6 KiB
C
111 lines
3.6 KiB
C
/*
|
|
* apple2.lores.c
|
|
*
|
|
* The Apple II has several modes of display, and one of those modes is
|
|
* low-resolution graphics. Graphics are shown on a 40x48 grid, where
|
|
* each cell in the grid consumes 4 rows or columns of pixels.
|
|
*
|
|
* It's possible in low-resolution graphics (and high-resolution, for
|
|
* that matter) to show text with graphics--that is to say, exactly the
|
|
* kind of text that would be seen in 40-column text mode. If text is
|
|
* shown (this is indicated through a "mixed" mode flag), then it will
|
|
* be rendered at the bottom of the screen, and the rows of pixels that
|
|
* would have been rendered in full graphical mode will be skipped.
|
|
*/
|
|
|
|
#include "apple2/apple2.h"
|
|
#include "apple2/lores.h"
|
|
#include "apple2/text.h"
|
|
|
|
/*
|
|
* These are the color codes for the lo-res colors that are available.
|
|
* Each byte in lo-res represents two visual cells, each 4 bytes high,
|
|
* which are indicated by considering the low and high 4 bits separately
|
|
* and matching them against the colors in the table below.
|
|
*
|
|
* These color values are the "NTSC Corrected" colors as defined in the
|
|
* Apple II Forever Anthology, v0.3, Hires reference (pulled from
|
|
* archive.org).
|
|
*/
|
|
static vm_color lores_colors[] = {
|
|
{ 0x00, 0x00, 0x00, 0x00 }, // black
|
|
{ 0x90, 0x17, 0x40, 0x00 }, // magenta
|
|
{ 0x40, 0x2c, 0xa5, 0x00 }, // dark blue
|
|
{ 0xd0, 0x43, 0xe5, 0x00 }, // purple
|
|
{ 0x00, 0x69, 0x40, 0x00 }, // dark green
|
|
{ 0x80, 0x80, 0x80, 0x00 }, // gray
|
|
{ 0x2f, 0x95, 0xe5, 0x00 }, // medium blue
|
|
{ 0xbf, 0xab, 0xff, 0x00 }, // light blue
|
|
{ 0x40, 0x54, 0x00, 0x00 }, // brown
|
|
{ 0xd0, 0x6a, 0x1a, 0x00 }, // orange
|
|
{ 0x80, 0x80, 0x80, 0x00 }, // gray
|
|
{ 0xff, 0x96, 0xbf, 0x00 }, // pink
|
|
{ 0x2f, 0xbc, 0x1a, 0x00 }, // light green
|
|
{ 0xbf, 0xd3, 0x5a, 0x00 }, // yellow
|
|
{ 0x6f, 0xe8, 0xbf, 0x00 }, // aquamarine
|
|
{ 0xff, 0xff, 0xff, 0x00 }, // white
|
|
};
|
|
|
|
|
|
/*
|
|
* Draw two cells on the low-resolution grid. Each byte address holds
|
|
* two cells-worth of data. We may delegate the render to the text
|
|
* render code if we're in mixed mode.
|
|
*/
|
|
void
|
|
apple2_lores_draw(apple2 *mach, size_t addr)
|
|
{
|
|
int row = apple2_text_row(addr),
|
|
col = apple2_text_col(addr);
|
|
|
|
if (row == -1 || col == -1) {
|
|
return;
|
|
}
|
|
|
|
// In low-resolution mode, the row number is analagous to the text
|
|
// row number, like so:
|
|
row *= 2;
|
|
|
|
// In mixed display mode, we have to render text in the lower rows
|
|
// of the screen
|
|
if ((mach->display_mode & DISPLAY_MIXED) && row >= 40) {
|
|
apple2_text_draw(mach, addr);
|
|
return;
|
|
}
|
|
|
|
vm_8bit byte = mos6502_get(mach->cpu, addr);
|
|
vm_8bit topcell = byte & 0xF,
|
|
botcell = byte >> 4;
|
|
|
|
vm_area dest;
|
|
|
|
// Cells are more like rectangles than squares
|
|
dest.width = 7;
|
|
dest.height = 4;
|
|
dest.xoff = 7 * col;
|
|
dest.yoff = 4 * row;
|
|
|
|
// Draw the top cell
|
|
vm_screen_set_color(mach->screen, apple2_lores_color(topcell));
|
|
vm_screen_draw_rect(mach->screen, &dest);
|
|
|
|
// And draw the bottom cell
|
|
dest.yoff += 4;
|
|
vm_screen_set_color(mach->screen, apple2_lores_color(botcell));
|
|
vm_screen_draw_rect(mach->screen, &dest);
|
|
}
|
|
|
|
/*
|
|
* Return the color that corresponds to the value in the given byte.
|
|
* Even though we receive a byte, lores color data is stored two cells
|
|
* to a byte, so all we ever get here will be contained within the first
|
|
* four bits; therefore we mask the byte as we index the lores colors
|
|
* table, to ensure a bad value doesn't end up returning a value out of
|
|
* bounds.
|
|
*/
|
|
vm_color
|
|
apple2_lores_color(vm_8bit byte)
|
|
{
|
|
return lores_colors[byte & 0xf];
|
|
}
|