Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add line-fill plot calls #150

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions video/agon_ttxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "ttxtfont.h"
#include "agon_palette.h"
#include "agon_screen.h"
#include "types.h"

#define COLOUR_BLACK 0x00
#define COLOUR_RED 0x30
Expand Down
56 changes: 56 additions & 0 deletions video/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "agon_screen.h"
#include "agon_fonts.h" // The Acorn BBC Micro Font
#include "agon_palette.h" // Colour lookup table
#include "agon_ttxt.h"
#include "cursor.h"
#include "sprites.h"
#include "viewport.h"
Expand All @@ -26,6 +27,8 @@ bool legacyModes = false; // Default legacy modes being false
bool rectangularPixels = false; // Pixels are square by default
uint8_t palette[64]; // Storage for the palette

extern bool ttxtMode; // Teletext mode
extern agon_ttxt ttxt_instance; // Teletext instance

// Copy the AGON font data from Flash to RAM
//
Expand Down Expand Up @@ -100,6 +103,41 @@ RGB888 getPixel(uint16_t x, uint16_t y) {
return RGB888(0,0,0);
}

// Horizontal scan until we find a pixel not non-equalto given colour
// returns x coordinate for the last pixel before the match
uint16_t scanH(int16_t x, int16_t y, RGB888 colour, int8_t direction = 1) {
uint16_t w = direction > 0 ? canvas->getWidth() - 1 : 0;
if (x < 0 || x >= canvas->getWidth()) return x;

while (x != w) {
RGB888 pixel = canvas->getPixel(x, y);
if (pixel == colour) {
x += direction;
} else {
return x - direction;
}
}

return w;
}

// Horizontal scan until we find a pixel matching the given colour
// returns x coordinate for the last pixel before the match
uint16_t scanHToMatch(int16_t x, int16_t y, RGB888 colour, int8_t direction = 1) {
uint16_t w = direction > 0 ? canvas->getWidth() - 1 : 0;
if (x < 0 || x >= canvas->getWidth()) return x;

while (x != w) {
RGB888 pixel = canvas->getPixel(x, y);
if (pixel == colour) {
return x - direction;
}
x += direction;
}

return w;
}

// Get the palette index for a given RGB888 colour
//
uint8_t getPaletteIndex(RGB888 colour) {
Expand Down Expand Up @@ -318,6 +356,24 @@ void plotLine(bool omitFirstPoint = false, bool omitLastPoint = false) {
}
}

// Fill horizontal line
//
void fillHorizontalLine(bool scanLeft, bool match, RGB888 matchColor) {
canvas->waitCompletion(false);
int16_t y = p1.Y;
int16_t x1 = scanLeft ? (match ? scanHToMatch(p1.X, y, matchColor, -1) : scanH(p1.X, y, matchColor, -1)) : p1.X;
int16_t x2 = match ? scanHToMatch(p1.X, y, matchColor, 1) : scanH(p1.X, y, matchColor, 1);
debug_log("fillHorizontalLine: (%d, %d) transformed to (%d,%d) -> (%d,%d)\n\r", p1.X, p1.Y, x1, y, x2, y);

if (x1 == x2 || x1 > x2) {
// nothing to draw
return;
}
canvas->moveTo(x1, y);
canvas->lineTo(x2, y);
pushPoint(x2, y);
}

// Point point
//
void plotPoint() {
Expand Down
21 changes: 16 additions & 5 deletions video/vdu.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#ifndef VDU_H
#define VDU_H

#include <HardwareSerial.h>

#include "agon.h"
#include "cursor.h"
#include "graphics.h"
#include "vdu_audio.h"
#include "vdu_sys.h"

extern bool consoleMode;
extern HardwareSerial DBGSerial;

// Handle VDU commands
//
void VDUStreamProcessor::vdu(uint8_t c) {
Expand Down Expand Up @@ -213,7 +218,7 @@ void VDUStreamProcessor::vdu_plot() {
plotLine(false, true);
break;
case 0x10: // dot-dash line
case 0x18: // dot-dash line, omitting last point
case 0x18: // dot-dash line, omitting first point
case 0x30: // dot-dash line, omitting first, pattern continued
case 0x38: // dot-dash line, omitting both, pattern continued
debug_log("plot dot-dash line not implemented\n\r");
Expand All @@ -228,23 +233,29 @@ void VDUStreamProcessor::vdu_plot() {
plotPoint();
break;
case 0x48: // line fill left/right to non-bg
case 0x58: // line fill right to bg
case 0x68: // line fill left/left to fg
case 0x78: // line fill right to non-fg
debug_log("plot line with fill left and/or right not implemented\n\r");
fillHorizontalLine(true, false, gbg);
break;
case 0x50: // triangle fill
setGraphicsFill(mode);
plotTriangle();
break;
case 0x58: // line fill right to bg
fillHorizontalLine(false, true, gbg);
break;
case 0x60: // rectangle fill
setGraphicsFill(mode);
plotRectangle();
break;
case 0x68: // line fill left/left to fg
fillHorizontalLine(true, true, gfg);
break;
case 0x70: // parallelogram fill
setGraphicsFill(mode);
plotParallelogram();
break;
case 0x78: // line fill right to non-fg
fillHorizontalLine(false, false, gfg);
break;
case 0x80: // flood to non-bg
case 0x88: // flood to fg
debug_log("plot flood fill not implemented\n\r");
Expand Down