Generalized print_character

Now has the option to pass a get_tile callback for different coordinate
systems. Can also turn off tilemap editing.
This commit is contained in:
jeffman 2017-04-15 12:49:47 -04:00
parent e49701cb5e
commit bc29d81c05
2 changed files with 36 additions and 9 deletions

View File

@ -17,6 +17,16 @@ int get_tile_number(int x, int y)
return m2_coord_table[x + ((y >> 1) * 28)] + (y & 1) * 32; return m2_coord_table[x + ((y >> 1) * 28)] + (y & 1) * 32;
} }
int get_tile_number_with_offset(int x, int y)
{
return get_tile_number(x, y) + *tile_offset;
}
int get_tile_number_grid(int x, int y)
{
return x + (y * 32);
}
int expand_bit_depth(byte row, int foreground) int expand_bit_depth(byte row, int foreground)
{ {
foreground &= 0xF; foreground &= 0xF;
@ -35,12 +45,22 @@ byte reduce_bit_depth(int row, int foreground)
} }
byte print_character(byte chr, byte x, byte y, byte font, byte foreground) byte print_character(byte chr, byte x, byte y, byte font, byte foreground)
{
return print_character_with_callback(chr, x, y, font, foreground, vram, &get_tile_number_with_offset, TRUE);
}
byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground)
{
return print_character_with_callback(chr, xOffset, 0, font, foreground, dest, &get_tile_number_grid, FALSE);
}
byte print_character_with_callback(byte chr, int x, int y, int font, int foreground,
int *dest, int (*getTileCallback)(int, int), int useTilemap)
{ {
int tileWidth = m2_font_widths[font]; int tileWidth = m2_font_widths[font];
int tileHeight = m2_font_heights[font]; int tileHeight = m2_font_heights[font];
int widths = m2_widths_table[font][chr]; int widths = m2_widths_table[font][chr];
int tileOffset = *tile_offset;
int paletteMask = *palette_mask; int paletteMask = *palette_mask;
byte const *glyphRows = &m2_font_table[font][chr * tileWidth * tileHeight * 8]; byte const *glyphRows = &m2_font_table[font][chr * tileWidth * tileHeight * 8];
@ -58,11 +78,11 @@ byte print_character(byte chr, byte x, byte y, byte font, byte foreground)
while (renderedWidth > 0) while (renderedWidth > 0)
{ {
// Glue the leftmost part of the glyph onto the rightmost part of the canvas // Glue the leftmost part of the glyph onto the rightmost part of the canvas
int tileIndex = get_tile_number(tileX + dTileX, tileY + dTileY) + tileOffset; int tileIndex = getTileCallback(tileX + dTileX, tileY + dTileY); //get_tile_number(tileX + dTileX, tileY + dTileY) + tileOffset;
for (int row = 0; row < 8; row++) for (int row = 0; row < 8; row++)
{ {
int canvasRow = vram[(tileIndex * 8) + row]; int canvasRow = dest[(tileIndex * 8) + row];
byte glyphRow = glyphRows[row + (dTileY * 8 * tileWidth) + (dTileX * 8)] & ((1 << leftPortionWidth) - 1); byte glyphRow = glyphRows[row + (dTileY * 8 * tileWidth) + (dTileX * 8)] & ((1 << leftPortionWidth) - 1);
glyphRow <<= (8 - leftPortionWidth); glyphRow <<= (8 - leftPortionWidth);
@ -71,20 +91,21 @@ byte print_character(byte chr, byte x, byte y, byte font, byte foreground)
canvasRow &= expandedGlyphRowMask; canvasRow &= expandedGlyphRowMask;
canvasRow |= expandedGlyphRow; canvasRow |= expandedGlyphRow;
vram[(tileIndex * 8) + row] = canvasRow; dest[(tileIndex * 8) + row] = canvasRow;
} }
(*tilemap)[tileX + dTileX + ((tileY + dTileY) * 32)] = paletteMask | tileIndex; if (useTilemap)
(*tilemap)[tileX + dTileX + ((tileY + dTileY) * 32)] = paletteMask | tileIndex;
if (renderedWidth - leftPortionWidth > 0 && leftPortionWidth < 8) if (renderedWidth - leftPortionWidth > 0 && leftPortionWidth < 8)
{ {
// Glue the rightmost part of the glyph onto the leftmost part of the next tile // Glue the rightmost part of the glyph onto the leftmost part of the next tile
// on the canvas // on the canvas
tileIndex = get_tile_number(tileX + dTileX + 1, tileY + dTileY) + tileOffset; tileIndex = getTileCallback(tileX + dTileX + 1, tileY + dTileY); //get_tile_number(tileX + dTileX + 1, tileY + dTileY) + tileOffset;
for (int row = 0; row < 8; row++) for (int row = 0; row < 8; row++)
{ {
int canvasRow = vram[(tileIndex * 8) + row]; int canvasRow = dest[(tileIndex * 8) + row];
byte glyphRow = glyphRows[row + (dTileY * 8 * tileWidth) + (dTileX * 8)] >> leftPortionWidth; byte glyphRow = glyphRows[row + (dTileY * 8 * tileWidth) + (dTileX * 8)] >> leftPortionWidth;
int expandedGlyphRow = expand_bit_depth(glyphRow, foreground); int expandedGlyphRow = expand_bit_depth(glyphRow, foreground);
@ -92,10 +113,11 @@ byte print_character(byte chr, byte x, byte y, byte font, byte foreground)
canvasRow &= expandedGlyphRowMask; canvasRow &= expandedGlyphRowMask;
canvasRow |= expandedGlyphRow; canvasRow |= expandedGlyphRow;
vram[(tileIndex * 8) + row] = canvasRow; dest[(tileIndex * 8) + row] = canvasRow;
} }
(*tilemap)[tileX + dTileX + 1 + ((tileY + dTileY) * 32)] = paletteMask | tileIndex; if (useTilemap)
(*tilemap)[tileX + dTileX + 1 + ((tileY + dTileY) * 32)] = paletteMask | tileIndex;
} }
renderedWidth -= 8; renderedWidth -= 8;

View File

@ -1,6 +1,8 @@
typedef unsigned char byte; typedef unsigned char byte;
#define QUESTION_MARK 0x1F; #define QUESTION_MARK 0x1F;
#define CPUFASTSET_FILL (0x1000000) #define CPUFASTSET_FILL (0x1000000)
#define TRUE 1
#define FALSE 0
unsigned short *tile_offset = (unsigned short*)0x30051EC; unsigned short *tile_offset = (unsigned short*)0x30051EC;
unsigned short *palette_mask = (unsigned short*)0x3005228; unsigned short *palette_mask = (unsigned short*)0x3005228;
@ -12,6 +14,9 @@ int get_tile_number(int x, int y);
int expand_bit_depth(byte row, int foreground); int expand_bit_depth(byte row, int foreground);
byte reduce_bit_depth(int row, int foreground); byte reduce_bit_depth(int row, int foreground);
byte print_character(byte chr, byte x, byte y, byte font, byte foreground); byte print_character(byte chr, byte x, byte y, byte font, byte foreground);
byte print_character_with_callback(byte chr, int x, int y, int font, int foreground,
int *dest, int (*getTileCallback)(int, int), int useTilemap);
byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground);
void weld_entry(WINDOW *window, byte *str); void weld_entry(WINDOW *window, byte *str);
void weld_entry_custom(WINDOW *window, byte *str, int font, int foreground); void weld_entry_custom(WINDOW *window, byte *str, int font, int foreground);
void clear_tile(int x, int y, int pixels); void clear_tile(int x, int y, int pixels);