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

improve scroll region function #159

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
139 changes: 82 additions & 57 deletions video/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,21 @@ char getScreenChar(uint16_t px, uint16_t py) {
// Now scan the screen and get the 8 byte pixel representation in charData
//
for (uint8_t y = 0; y < 8; y++) {
charRow = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the whitespace changes in this PR... inconsistent formatting bugs me....

for (uint8_t x = 0; x < 8; x++) {
pixel = canvas->getPixel(px + x, py + y);
if (!(pixel.R == R && pixel.G == G && pixel.B == B)) {
charRow = 0;
for (uint8_t x = 0; x < 8; x++) {
pixel = canvas->getPixel(px + x, py + y);
if (!(pixel.R == R && pixel.G == G && pixel.B == B)) {
charRow |= (0x80 >> x);
}
}
charData[y] = charRow;
}
}
charData[y] = charRow;
}
//
// Finally try and match with the character set array
//
for (auto i = 32; i <= 255; i++) {
if (cmpChar(charData, &fabgl::FONT_AGON_DATA[i * 8], 8)) {
return i;
if (cmpChar(charData, &fabgl::FONT_AGON_DATA[i * 8], 8)) {
return i;
}
}
}
Expand Down Expand Up @@ -127,7 +127,7 @@ void setPalette(uint8_t l, uint8_t p, uint8_t r, uint8_t g, uint8_t b) {
col = RGB888(r, g, b);
} else if (p < 64) { // If p < 64, then look the value up in the colour lookup table
col = colourLookup[p];
} else {
} else {
debug_log("vdu_palette: p=%d not supported\n\r", p);
return;
}
Expand Down Expand Up @@ -157,7 +157,7 @@ void resetPalette(const uint8_t colours[]) {
//
fabgl::PaintOptions getPaintOptions(uint8_t mode, fabgl::PaintOptions priorPaintOptions) {
fabgl::PaintOptions p = priorPaintOptions;

switch (mode) {
case 0: p.NOT = 0; p.swapFGBG = 0; break;
case 4: p.NOT = 1; p.swapFGBG = 0; break;
Expand All @@ -178,7 +178,7 @@ void setTextColour(uint8_t colour) {
}
else if (colour >= 128 && colour < 192) {
tbg = colourLookup[c];
debug_log("vdu_colour: tbg %d = %02X : %02X,%02X,%02X\n\r", colour, c, tbg.R, tbg.G, tbg.B);
debug_log("vdu_colour: tbg %d = %02X : %02X,%02X,%02X\n\r", colour, c, tbg.R, tbg.G, tbg.B);
}
else {
debug_log("vdu_colour: invalid colour %d\n\r", colour);
Expand All @@ -189,7 +189,7 @@ void setTextColour(uint8_t colour) {
//
void setGraphicsColour(uint8_t mode, uint8_t colour) {
if (ttxtMode) return;

uint8_t c = palette[colour % getVGAColourDepth()];

if (mode <= 6) {
Expand All @@ -216,15 +216,15 @@ void setGraphicsColour(uint8_t mode, uint8_t colour) {
void clearViewport(Rect * viewport) {
if (ttxtMode) {
ttxt_instance.cls();
} else {
if (canvas) {
if (useViewports) {
canvas->fillRectangle(*viewport);
}
else {
canvas->clear();
} else {
if (canvas) {
if (useViewports) {
canvas->fillRectangle(*viewport);
}
else {
canvas->clear();
}
}
}
}
}

Expand Down Expand Up @@ -330,7 +330,7 @@ void plotTriangle() {
Point p[3] = {
p3,
p2,
p1,
p1,
};
canvas->drawPath(p, 3);
canvas->fillPath(p, 3);
Expand Down Expand Up @@ -430,20 +430,20 @@ void plotBitmap() {
//
void plotCharacter(char c) {
if (ttxtMode) {
ttxt_instance.draw_char(activeCursor->X, activeCursor->Y, c);
} else {
if (textCursorActive()) {
canvas->setClippingRect(defaultViewport);
ttxt_instance.draw_char(activeCursor->X, activeCursor->Y, c);
} else {
if (textCursorActive()) {
canvas->setClippingRect(defaultViewport);
canvas->setPenColor(tfg);
canvas->setBrushColor(tbg);
canvas->setPaintOptions(tpo);
} else {
canvas->setClippingRect(graphicsViewport);
canvas->setPenColor(gfg);
canvas->setPaintOptions(gpo);
} else {
canvas->setClippingRect(graphicsViewport);
canvas->setPenColor(gfg);
canvas->setPaintOptions(gpo);
}
canvas->drawChar(activeCursor->X, activeCursor->Y, c);
}
}
cursorRight();
}

Expand Down Expand Up @@ -479,17 +479,17 @@ void drawCursor(Point p) {


// Clear the screen
//
//
void cls(bool resetViewports) {
if (resetViewports) {
if (ttxtMode) {
ttxt_instance.set_window(0,24,39,0);
if (ttxtMode) {
ttxt_instance.set_window(0,24,39,0);
}
viewportReset();
}
if (canvas) {
canvas->setPenColor(tfg);
canvas->setBrushColor(tbg);
canvas->setBrushColor(tbg);
canvas->setPaintOptions(tpo);
clearViewport(getViewport(VIEWPORT_TEXT));
}
Expand All @@ -506,7 +506,7 @@ void cls(bool resetViewports) {
void clg() {
if (canvas) {
canvas->setPenColor(gfg);
canvas->setBrushColor(gbg);
canvas->setBrushColor(gbg);
canvas->setPaintOptions(gpo);
clearViewport(getViewport(VIEWPORT_GRAPHICS));
}
Expand Down Expand Up @@ -566,12 +566,12 @@ int8_t change_mode(uint8_t mode) {
errVal = change_resolution(2, VGA_640x240_60Hz);
break;
case 7:
errVal = change_resolution(16, VGA_640x480_60Hz);
if (errVal == 0) {
errVal = ttxt_instance.init();
if (errVal == 0) ttxtMode = true;
}
break;
errVal = change_resolution(16, VGA_640x480_60Hz);
if (errVal == 0) {
errVal = ttxt_instance.init();
if (errVal == 0) ttxtMode = true;
}
break;
case 8:
errVal = change_resolution(64, QVGA_320x240_60Hz); // VGA "Mode X"
break;
Expand Down Expand Up @@ -628,7 +628,7 @@ int8_t change_mode(uint8_t mode) {
break;
case 138:
errVal = change_resolution(4, QVGA_320x240_60Hz, true);
break;
break;
case 139:
errVal = change_resolution(2, QVGA_320x240_60Hz, true);
break;
Expand All @@ -643,7 +643,7 @@ int8_t change_mode(uint8_t mode) {
break;
case 143:
errVal = change_resolution(2, VGA_320x200_70Hz, true);
break;
break;
}
if (errVal != 0) {
return errVal;
Expand Down Expand Up @@ -716,23 +716,48 @@ void setLegacyModes(bool legacy) {
void scrollRegion(Rect * region, uint8_t direction, int16_t movement) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only real changes in this PR are within this function

canvas->setScrollingRegion(region->X1, region->Y1, region->X2, region->Y2);
if (ttxtMode) {
if (direction == 3) ttxt_instance.scroll();
} else {
if (direction == 3) ttxt_instance.scroll();
} else {
canvas->setPenColor(tbg);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line is the fix for #58

auto moveX = 0;
auto moveY = 0;
switch (direction) {
case 0: // Right
canvas->scroll(movement, 0);
break;
case 1: // Left
canvas->scroll(-movement, 0);
case 0: // Right
moveX = 1;
break;
case 1: // Left
moveX = -1;
break;
case 2: // Down
moveY = 1;
break;
case 2: // Down
canvas->scroll(0, movement);
case 3: // Up
moveY = -1;
break;
case 3: // Up
canvas->scroll(0, -movement);
case 4: // positive X
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acorn's version of this command supports directions 4-7, whose behaviour varies depending on the current cursorBehaviour variable, as set via VDU 23,16
since we have partial support for cursorBehaviour it makes some sense to implement these values

moveX = cursorBehaviour & 0x02 ? -1 : 1;
break;
}
}
case 5: // negative X
moveX = cursorBehaviour & 0x02 ? 1 : -1;
break;
case 6: // positive Y
moveY = cursorBehaviour & 0x04 ? -1 : 1;
break;
case 7: // negative Y
moveY = cursorBehaviour & 0x04 ? 1 : -1;
break;
}
if (moveX != 0 || moveY != 0) {
if (movement == 0) {
if (moveX != 0) {
movement = fontW;
} else {
movement = fontH;
}
}
Comment on lines +751 to +757
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acorn's version of this command differs to ours with respect to how the movement value is interpreted. they only support 0 and 1, where 0 indicates movement by a single character, and 1 by a single byte (which means a variable number of pixels depending on screen mode). values greater than 1 are treated as if they were 1

our version treats the movement value as a number of pixels. this adds in support for 0 to indicate "whole character", which gives us slightly better compatibility with Acorn's version

canvas->scroll(movement * moveX, movement * moveY);
}
}
}

#endif