Shaun Reed 164af20d56 Fix dependencies for each component.
Add ability to clear LCD screen, and write at a label position.
2025-11-02 16:43:35 -05:00

99 lines
4.1 KiB
C

/*#############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2025 Shaun Reed, all rights reserved ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com ##
##############################################################################
*/
/**
* Calculate byte offset for the pixel at [x,y] within a horizontally-mapped
* monochrome uint8 draw buffer, using the initialized horizontal resolution.
*
* We use `>> 3` because each pixel requires 1 bit, but each uint8 in the draw
* buffer can hold 8 bits. To find the uint8 value in our draw buffer that
* stores this pixel's value we must compensate for this when using pixel
* coordinates in byte math.
*
* Therefore, each uint8 in the draw buffer stores the state of 8 pixels.
* Below is an example of calculating for [x, y] pixel coordinates [20, 10].
* The example uses a horizontal resolution of 128.
*
* For the horizontal case, each row (y) of the image is represented by
* `hor_res >> 3` bytes (16). The byte-offset of the first pixel in the 10th
* row for example is `16 * 10` = 160.
*
* Since the pixels are stored horizontally we must calculate the 20th pixel
* column (x) as `160 + (20 >> 3)`, or `160 + (20 / 8)` to get a final offset
* of 162.
*
* @param x X pixel coordinate to find byte offset.
* @param y Y pixel coordinate to find byte offset.
* @param hor_res horizontal resolution of the display.
* @return byte offset for a single-byte monochrome pixel at [x,y].
*/
static ptrdiff_t horizontal_byte_offset_long(const int32_t x, const int32_t y,
const int32_t hor_res)
{
// Convert pixel (bit) coordinates to byte coordinates in the draw buffer.
return (hor_res >> 3) * y + (x >> 3);
}
/**
* Calculate byte offset for the pixel at [x,y] within a vertically-mapped
* monochrome uint8 draw buffer, using the initialized horizontal resolution.
*
* We use `>> 3` because each pixel requires 1 bit, but each uint8 in the draw
* buffer can hold 8 bits. To find the uint8 value in our draw buffer that
* stores this pixel's value we must compensate for this when using pixel
* coordinates in byte math.
*
* Therefore, each uint8 in the draw buffer stores the state of 8 pixels.
* Below is an example of calculating for [x, y] pixel coordinates [20, 10].
* The example uses a horizontal resolution of 128.
*
* For the vertical case, each row (y) of the image is represented by
* `hor_res` bytes (128) - one for each column (x). Because the pixels are
* stored vertically, the byte-offset of the first pixel in the 10th row is
* `128 * (10 >> 3)` or * `128 * (10 / 8)` = 128.
*
* From this location we can simply calculate the 20th pixel column (x) as
* `128 + 20` to get a final offset of 148, because the pixels are stored in a
* columnar format.
*
* @param x X pixel coordinate to find byte offset.
* @param y Y pixel coordinate to find byte offset.
* @param hor_res horizontal resolution of the display.
* @return byte offset for a single-byte monochrome pixel at [x,y].
*/
static ptrdiff_t vertical_byte_offset_long(const int32_t x, const int32_t y,
const int32_t hor_res)
{
// Convert pixel (bit) coordinates to byte coordinates in the draw buffer.
return hor_res * (y >> 3) + x;
}
/**
* Finds the Most Significant Bit location of bit `i` in a byte.
*
* MSB LSB
* bits 7 6 5 4 3 2 1 0
* data 8 7 6 5 4 3 2 1
* Left Right
*
* @return bitmask for MSB location of `i`.
*/
static uint8_t msb_mask(const int32_t i) { return 1 << (7 - i % 8); }
/**
* Finds the Least Significant Bit location of bit `i` in a byte.
*
* LSB MSB
* bits 0 1 2 3 4 5 6 7
* data 1 2 3 4 5 6 7 8
* Left Right
*
* @return bitmask for LSB location of `i`.
*/
static uint8_t lsb_mask(const int32_t i) { return 1 << (i % 8); }