Skip to content
Merged
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
55 changes: 37 additions & 18 deletions firmware/src/Screens/EmulatorScreen/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,33 +145,52 @@ void Renderer::drawSpectrumScreen() {
}
uint16_t tftInkColor = specpal565[inkColor];
uint16_t tftPaperColor = specpal565[paperColor];
const uint32_t u32Lookup[4] = {
tftPaperColor | (tftPaperColor << 16), // 00
tftPaperColor | (tftInkColor << 16), // 01
tftInkColor | (tftPaperColor << 16), // 10
tftInkColor | (tftInkColor << 16) // 11
};
for (int y = 0; y < 8; y++)
{
// read the value of the pixels
int screenY = attrY * 8 + y;
int col = ((attrX * 8) & B11111000) >> 3;
int scan = (screenY & B11000000) + ((screenY & B111) << 3) + ((screenY & B111000) >> 3);
uint8_t row = *(pixelBase + 32 * scan + col);
uint8_t rowCopy = *(pixelBaseCopy + 32 * scan + col);
int screenY = attrY * 8;
Comment on lines 154 to +157
Copy link
Preview

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

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

The calculation of screenY inside the loop is inefficient since it's constant for all iterations. Consider moving this calculation outside the loop as it was in the original code (screenY = attrY * 8 + y).

Copilot uses AI. Check for mistakes.

int scan = (screenY & B11000000) + (y << 3) + ((screenY & B111000) >> 3);
uint8_t row = *(pixelBase + 32 * scan + attrX);
uint8_t rowCopy = *(pixelBaseCopy + 32 * scan + attrX);
// check for changes in the pixel data
if (row != rowCopy)
{
dirty = true;
*(pixelBaseCopy + 32 * scan + col) = row;
*(pixelBaseCopy + 32 * scan + attrX) = row;
}
uint16_t *pixelAddress = pixelBuffer + 256 * y + attrX * 8;
for (int x = 0; x < 8; x++)
{
if (row & 128)
{
*pixelAddress = tftInkColor;
}
else
{
*pixelAddress = tftPaperColor;
}
pixelAddress++;
row = row << 1;
// Since the ESP32 is a 32-bit processor with a 32-bit memory bus,
// it's more efficient to write 32-bits at a time. So...calculate
// pairs of pixels and avoid conditional tests and branches.
// Check for the 2 optimal cases of pure foreground or background
if (row == 0) {
uint32_t u32Clr = tftPaperColor | (tftPaperColor << 16);
uint32_t *d32 = (uint32_t *)pixelAddress;
*d32++ = u32Clr;
*d32++ = u32Clr;
*d32++ = u32Clr;
*d32++ = u32Clr;
pixelAddress += 8;
Copy link
Preview

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

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

The pixelAddress increment is unnecessary and potentially incorrect. The pointer arithmetic already advances d32 by 4 positions (16 bytes = 8 uint16_t elements), so incrementing pixelAddress by 8 additional elements may cause buffer overrun or incorrect positioning for subsequent operations.

Copilot uses AI. Check for mistakes.

} else if (row == 0xff) {
uint32_t u32Clr = tftInkColor | (tftInkColor << 16);
uint32_t *d32 = (uint32_t *)pixelAddress;
*d32++ = u32Clr;
*d32++ = u32Clr;
*d32++ = u32Clr;
*d32++ = u32Clr;
pixelAddress += 8;
Copy link
Preview

Copilot AI Sep 8, 2025

Choose a reason for hiding this comment

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

The pixelAddress increment is unnecessary and potentially incorrect. The pointer arithmetic already advances d32 by 4 positions (16 bytes = 8 uint16_t elements), so incrementing pixelAddress by 8 additional elements may cause buffer overrun or incorrect positioning for subsequent operations.

Copilot uses AI. Check for mistakes.

} else { // Otherwise use a lookup table to write pairs of pixels
uint32_t *d32 = (uint32_t *)pixelAddress;
*d32++ = u32Lookup[row >> 6];
*d32++ = u32Lookup[(row >> 4) & 3];
*d32++ = u32Lookup[(row >> 2) & 3];
*d32++ = u32Lookup[row & 3];
}
}
}
Expand Down