kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Merge pull request #682 from pimoroni/feature/inky73c++
Inky 7.3: C++ library and JPEG example compatibility.pull/533/head
commit
63de02016f
|
@ -1,14 +1,30 @@
|
|||
set(OUTPUT_NAME inky_frame_day_planner)
|
||||
|
||||
# Inky Frame 5.7"
|
||||
add_executable(
|
||||
${OUTPUT_NAME}
|
||||
inky_frame_day_planner
|
||||
inky_frame_day_planner.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${OUTPUT_NAME} pico_stdlib inky_frame hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics)
|
||||
target_link_libraries(inky_frame_day_planner pico_stdlib inky_frame hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics)
|
||||
|
||||
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||
pico_enable_stdio_usb(inky_frame_day_planner 1)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
||||
pico_add_extra_outputs(inky_frame_day_planner)
|
||||
|
||||
# Inky Frame 7.3"
|
||||
add_executable(
|
||||
inky_frame_7_day_planner
|
||||
inky_frame_day_planner.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(inky_frame_7_day_planner pico_stdlib inky_frame_7 hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics)
|
||||
|
||||
pico_enable_stdio_usb(inky_frame_7_day_planner 1)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(inky_frame_7_day_planner)
|
||||
|
||||
target_compile_definitions(inky_frame_7_day_planner PUBLIC INKY_FRAME_7)
|
||||
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
#ifdef INKY_FRAME_7
|
||||
#include "libraries/inky_frame_7/inky_frame_7.hpp"
|
||||
#else
|
||||
#include "libraries/inky_frame/inky_frame.hpp"
|
||||
#endif
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
|
|
|
@ -1,14 +1,28 @@
|
|||
set(OUTPUT_NAME inky_frame_jpeg_image)
|
||||
|
||||
add_executable(
|
||||
${OUTPUT_NAME}
|
||||
inky_frame_jpeg_image
|
||||
inky_frame_jpeg_image.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${OUTPUT_NAME} pico_stdlib jpegdec inky_frame fatfs hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics)
|
||||
target_link_libraries(inky_frame_jpeg_image pico_stdlib jpegdec inky_frame fatfs hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics)
|
||||
|
||||
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||
pico_enable_stdio_usb(inky_frame_jpeg_image 1)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
||||
pico_add_extra_outputs(inky_frame_jpeg_image)
|
||||
|
||||
|
||||
add_executable(
|
||||
inky_frame_7_jpeg_image
|
||||
inky_frame_jpeg_image.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(inky_frame_7_jpeg_image pico_stdlib jpegdec inky_frame_7 fatfs hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics)
|
||||
|
||||
pico_enable_stdio_usb(inky_frame_7_jpeg_image 1)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(inky_frame_7_jpeg_image)
|
||||
|
||||
target_compile_definitions(inky_frame_7_jpeg_image PUBLIC INKY_FRAME_7)
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
|
||||
#include "JPEGDEC.h"
|
||||
|
||||
#ifdef INKY_FRAME_7
|
||||
#include "libraries/inky_frame_7/inky_frame_7.hpp"
|
||||
#else
|
||||
#include "libraries/inky_frame/inky_frame.hpp"
|
||||
#endif
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
|
@ -65,6 +69,36 @@ int jpegdec_draw_callback(JPEGDRAW *draw) {
|
|||
return 1; // continue drawing
|
||||
}
|
||||
|
||||
// Draw to the nearest colour instead of dithering
|
||||
int jpegdec_draw_posterize_callback(JPEGDRAW *draw) {
|
||||
uint16_t *p = draw->pPixels;
|
||||
|
||||
int xo = jpeg_decode_options.x;
|
||||
int yo = jpeg_decode_options.y;
|
||||
|
||||
for(int y = 0; y < draw->iHeight; y++) {
|
||||
for(int x = 0; x < draw->iWidth; x++) {
|
||||
int sx = ((draw->x + x + xo) * jpeg_decode_options.w) / jpeg.getWidth();
|
||||
int sy = ((draw->y + y + yo) * jpeg_decode_options.h) / jpeg.getHeight();
|
||||
|
||||
if(xo + sx > 0 && xo + sx < inky.bounds.w && yo + sy > 0 && yo + sy < inky.bounds.h) {
|
||||
int closest = RGB(RGB565(*p)).closest(inky.palette, inky.palette_size);
|
||||
if (closest != -1) {
|
||||
inky.set_pen(closest);
|
||||
inky.set_pixel({xo + sx, yo + sy});
|
||||
} else {
|
||||
inky.set_pen(0);
|
||||
inky.set_pixel({xo + sx, yo + sy});
|
||||
}
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1; // continue drawing
|
||||
}
|
||||
|
||||
void draw_jpeg(std::string filename, int x, int y, int w, int h) {
|
||||
|
||||
// TODO: this is a horrible way to do it but we need to pass some parameters
|
||||
|
@ -81,7 +115,8 @@ void draw_jpeg(std::string filename, int x, int y, int w, int h) {
|
|||
jpegdec_close_callback,
|
||||
jpegdec_read_callback,
|
||||
jpegdec_seek_callback,
|
||||
jpegdec_draw_callback);
|
||||
jpegdec_draw_callback // Try jpegdec_draw_posterize_callback
|
||||
);
|
||||
|
||||
jpeg.setPixelType(RGB565_BIG_ENDIAN);
|
||||
|
||||
|
@ -130,7 +165,7 @@ int main() {
|
|||
}; // Wait for debugger
|
||||
}
|
||||
|
||||
filename = "butterfly-600x448.jpg";
|
||||
filename = "shutterstock_172537049.jpg";
|
||||
|
||||
//inky.led(InkyFrame::LED_E, 255);
|
||||
//sleep_ms(1000);
|
||||
|
@ -169,7 +204,7 @@ int main() {
|
|||
printf("done!\n");
|
||||
|
||||
printf("Displaying file: %s\n", filename.c_str());
|
||||
draw_jpeg(filename, 0, 0, 600, 448);
|
||||
draw_jpeg(filename, 0, 0, inky.width, inky.height);
|
||||
printf("done!\n");
|
||||
|
||||
inky.update();
|
||||
|
|
|
@ -36,6 +36,7 @@ add_subdirectory(inventor2040w)
|
|||
add_subdirectory(adcfft)
|
||||
add_subdirectory(jpegdec)
|
||||
add_subdirectory(inky_frame)
|
||||
add_subdirectory(inky_frame_7)
|
||||
add_subdirectory(galactic_unicorn)
|
||||
add_subdirectory(gfx_pack)
|
||||
add_subdirectory(interstate75)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
include(inky_frame_7.cmake)
|
|
@ -0,0 +1,13 @@
|
|||
set(LIB_NAME inky_frame_7)
|
||||
add_library(${LIB_NAME} INTERFACE)
|
||||
|
||||
target_sources(${LIB_NAME} INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${LIB_NAME} INTERFACE hardware_i2c pico_graphics hardware_spi hardware_pwm bitmap_fonts hershey_fonts pico_stdlib sdcard fatfs pcf85063a psram_display inky73 jpegdec)
|
||||
|
||||
target_compile_options(${LIB_NAME} INTERFACE -Wno-error=reorder)
|
|
@ -0,0 +1,166 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <functional>
|
||||
|
||||
#include "hardware/pwm.h"
|
||||
#include "hardware/watchdog.h"
|
||||
|
||||
#include "inky_frame_7.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
void gpio_configure(uint gpio, bool dir, bool value = false) {
|
||||
gpio_set_function(gpio, GPIO_FUNC_SIO); gpio_set_dir(gpio, dir); gpio_put(gpio, value);
|
||||
}
|
||||
|
||||
void gpio_configure_pwm(uint gpio) {
|
||||
pwm_config cfg = pwm_get_default_config();
|
||||
pwm_set_wrap(pwm_gpio_to_slice_num(gpio), 65535);
|
||||
pwm_init(pwm_gpio_to_slice_num(gpio), &cfg, true);
|
||||
gpio_set_function(gpio, GPIO_FUNC_PWM);
|
||||
}
|
||||
|
||||
void InkyFrame::init() {
|
||||
// keep the pico awake by holding vsys_en high
|
||||
gpio_set_function(HOLD_VSYS_EN, GPIO_FUNC_SIO);
|
||||
gpio_set_dir(HOLD_VSYS_EN, GPIO_OUT);
|
||||
gpio_put(HOLD_VSYS_EN, true);
|
||||
|
||||
// setup the shift register
|
||||
gpio_configure(SR_CLOCK, GPIO_OUT, true);
|
||||
gpio_configure(SR_LATCH, GPIO_OUT, true);
|
||||
gpio_configure(SR_OUT, GPIO_IN);
|
||||
|
||||
// determine wake up event
|
||||
if(read_shift_register_bit(BUTTON_A)) {_wake_up_event = BUTTON_A_EVENT;}
|
||||
if(read_shift_register_bit(BUTTON_B)) {_wake_up_event = BUTTON_B_EVENT;}
|
||||
if(read_shift_register_bit(BUTTON_C)) {_wake_up_event = BUTTON_C_EVENT;}
|
||||
if(read_shift_register_bit(BUTTON_D)) {_wake_up_event = BUTTON_D_EVENT;}
|
||||
if(read_shift_register_bit(BUTTON_E)) {_wake_up_event = BUTTON_E_EVENT;}
|
||||
if(read_shift_register_bit(RTC_ALARM)) {_wake_up_event = RTC_ALARM_EVENT;}
|
||||
if(read_shift_register_bit(EXTERNAL_TRIGGER)) {_wake_up_event = EXTERNAL_TRIGGER_EVENT;}
|
||||
// there are other reasons a wake event can occur: connect power via usb,
|
||||
// connect a battery, or press the reset button. these cannot be
|
||||
// disambiguated so we don't attempt to report them
|
||||
|
||||
// Disable display update busy wait, we'll handle it ourselves
|
||||
inky73.set_blocking(false);
|
||||
|
||||
// initialise the rtc
|
||||
rtc.init();
|
||||
|
||||
// setup led pwm
|
||||
gpio_configure_pwm(LED_A);
|
||||
gpio_configure_pwm(LED_B);
|
||||
gpio_configure_pwm(LED_C);
|
||||
gpio_configure_pwm(LED_D);
|
||||
gpio_configure_pwm(LED_E);
|
||||
gpio_configure_pwm(LED_ACTIVITY);
|
||||
gpio_configure_pwm(LED_CONNECTION);
|
||||
}
|
||||
|
||||
bool InkyFrame::is_busy() {
|
||||
// check busy flag on shift register
|
||||
bool busy = !read_shift_register_bit(Flags::EINK_BUSY);
|
||||
return busy;
|
||||
}
|
||||
|
||||
void InkyFrame::update(bool blocking) {
|
||||
while(is_busy()) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
inky73.update((PicoGraphics_PenInky7 *)this);
|
||||
while(is_busy()) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
inky73.power_off();
|
||||
}
|
||||
|
||||
bool InkyFrame::pressed(Button button) {
|
||||
return read_shift_register_bit(button);
|
||||
}
|
||||
|
||||
// set the LED brightness by generating a gamma corrected target value for
|
||||
// the 16-bit pwm channel. brightness values are from 0 to 100.
|
||||
void InkyFrame::led(LED led, uint8_t brightness) {
|
||||
uint16_t value =
|
||||
(uint16_t)(pow((float)(brightness) / 100.0f, 2.8) * 65535.0f + 0.5f);
|
||||
pwm_set_gpio_level(led, value);
|
||||
}
|
||||
|
||||
uint8_t InkyFrame::read_shift_register() {
|
||||
gpio_put(SR_LATCH, false); sleep_us(1);
|
||||
gpio_put(SR_LATCH, true); sleep_us(1);
|
||||
|
||||
uint8_t result = 0;
|
||||
uint8_t bits = 8;
|
||||
while(bits--) {
|
||||
result <<= 1;
|
||||
result |= gpio_get(SR_OUT) ? 1 : 0;
|
||||
|
||||
gpio_put(SR_CLOCK, false); sleep_us(1);
|
||||
gpio_put(SR_CLOCK, true); sleep_us(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InkyFrame::read_shift_register_bit(uint8_t index) {
|
||||
return read_shift_register() & (1U << index);
|
||||
}
|
||||
|
||||
void InkyFrame::sleep(int wake_in_minutes) {
|
||||
if(wake_in_minutes != -1) {
|
||||
// set an alarm to wake inky up in wake_in_minutes - the maximum sleep
|
||||
// is 255 minutes or around 4.5 hours which is the longest timer the RTC
|
||||
// supports, to sleep any longer we need to specify a date and time to
|
||||
// wake up
|
||||
rtc.set_timer(wake_in_minutes, PCF85063A::TIMER_TICK_1_OVER_60HZ);
|
||||
rtc.enable_timer_interrupt(true, false);
|
||||
}
|
||||
|
||||
// release the vsys hold pin so that inky can go to sleep
|
||||
gpio_put(HOLD_VSYS_EN, false);
|
||||
while(true){};
|
||||
}
|
||||
|
||||
void InkyFrame::sleep_until(int second, int minute, int hour, int day) {
|
||||
if(second != -1 || minute != -1 || hour != -1 || day != -1) {
|
||||
// set an alarm to wake inky up at the specified time and day
|
||||
rtc.set_alarm(second, minute, hour, day);
|
||||
rtc.enable_alarm_interrupt(true);
|
||||
}
|
||||
|
||||
// release the vsys hold pin so that inky can go to sleep
|
||||
gpio_put(HOLD_VSYS_EN, false);
|
||||
}
|
||||
|
||||
// Display a portion of an image (icon sheet) at dx, dy
|
||||
void InkyFrame::icon(const uint8_t *data, int sheet_width, int icon_size, int index, int dx, int dy) {
|
||||
image(data, sheet_width, icon_size * index, 0, icon_size, icon_size, dx, dy);
|
||||
}
|
||||
|
||||
// Display an image that fills the screen (286*128)
|
||||
void InkyFrame::image(const uint8_t* data) {
|
||||
image(data, width, 0, 0, width, height, 0, 0);
|
||||
}
|
||||
|
||||
// Display an image smaller than the screen (sw*sh) at dx, dy
|
||||
void InkyFrame::image(const uint8_t *data, int w, int h, int x, int y) {
|
||||
image(data, w, 0, 0, w, h, x, y);
|
||||
}
|
||||
|
||||
void InkyFrame::image(const uint8_t *data, int stride, int sx, int sy, int dw, int dh, int dx, int dy) {
|
||||
for(auto y = 0; y < dh; y++) {
|
||||
for(auto x = 0; x < dw; x++) {
|
||||
|
||||
uint32_t o = ((y + sy) * (stride / 2)) + ((x + sx) / 2);
|
||||
uint8_t d = ((x + sx) & 0b1) ? data[o] >> 4 : data[o] & 0xf;
|
||||
|
||||
// draw the pixel
|
||||
set_pen(d);
|
||||
pixel({dx + x, dy + y});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "drivers/inky73/inky73.hpp"
|
||||
#include "drivers/psram_display/psram_display.hpp"
|
||||
#include "drivers/pcf85063a/pcf85063a.hpp"
|
||||
#include "drivers/fatfs/ff.h"
|
||||
|
||||
#include "libraries/pico_graphics/pico_graphics.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
class InkyFrame : public PicoGraphics_PenInky7 {
|
||||
public:
|
||||
enum Button : uint8_t {
|
||||
BUTTON_A = 0,
|
||||
BUTTON_B = 1,
|
||||
BUTTON_C = 2,
|
||||
BUTTON_D = 3,
|
||||
BUTTON_E = 4
|
||||
};
|
||||
|
||||
enum LED : uint8_t {
|
||||
LED_ACTIVITY = 6,
|
||||
LED_CONNECTION = 7,
|
||||
LED_A = 11,
|
||||
LED_B = 12,
|
||||
LED_C = 13,
|
||||
LED_D = 14,
|
||||
LED_E = 15
|
||||
};
|
||||
|
||||
enum Flags : uint8_t {
|
||||
RTC_ALARM = 5,
|
||||
EXTERNAL_TRIGGER = 6,
|
||||
EINK_BUSY = 7
|
||||
};
|
||||
|
||||
enum WakeUpEvent : uint8_t {
|
||||
UNKNOWN_EVENT = 0,
|
||||
BUTTON_A_EVENT = 1,
|
||||
BUTTON_B_EVENT = 2,
|
||||
BUTTON_C_EVENT = 3,
|
||||
BUTTON_D_EVENT = 4,
|
||||
BUTTON_E_EVENT = 5,
|
||||
RTC_ALARM_EVENT = 6,
|
||||
EXTERNAL_TRIGGER_EVENT = 7,
|
||||
};
|
||||
|
||||
enum Pen : uint8_t {
|
||||
BLACK = 0,
|
||||
WHITE = 1,
|
||||
GREEN = 2,
|
||||
BLUE = 3,
|
||||
RED = 4,
|
||||
YELLOW = 5,
|
||||
ORANGE = 6,
|
||||
CLEAN = 7,
|
||||
TAUPE = 7
|
||||
};
|
||||
|
||||
protected:
|
||||
WakeUpEvent _wake_up_event = UNKNOWN_EVENT;
|
||||
|
||||
enum Pin {
|
||||
HOLD_VSYS_EN = 2,
|
||||
I2C_INT = 3,
|
||||
I2C_SDA = 4,
|
||||
I2C_SCL = 5,
|
||||
SR_CLOCK = 8,
|
||||
SR_LATCH = 9,
|
||||
SR_OUT = 10,
|
||||
MISO = 16,
|
||||
EINK_CS = 17,
|
||||
CLK = 18,
|
||||
MOSI = 19,
|
||||
SD_DAT0 = 19,
|
||||
SD_DAT1 = 20,
|
||||
SD_DAT2 = 21,
|
||||
SD_DAT3 = 22,
|
||||
SD_CS = 22,
|
||||
ADC0 = 26,
|
||||
EINK_RESET = 27,
|
||||
EINK_DC = 28
|
||||
};
|
||||
|
||||
public:
|
||||
PSRamDisplay ramDisplay;
|
||||
Inky73 inky73;
|
||||
I2C i2c;
|
||||
PCF85063A rtc;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
// Default 7.3" constructor
|
||||
InkyFrame() : InkyFrame(800, 480) {};
|
||||
|
||||
// 600x448 for 5.7"
|
||||
// 640x400 for 4.0"
|
||||
InkyFrame(int width, int height) :
|
||||
ramDisplay(width, height),
|
||||
PicoGraphics_PenInky7(width, height, ramDisplay),
|
||||
inky73(width, height),
|
||||
i2c(4, 5),
|
||||
rtc(&i2c),
|
||||
width(width),
|
||||
height(height) {
|
||||
}
|
||||
|
||||
void init();
|
||||
|
||||
// wake/sleep management
|
||||
void sleep(int wake_in_minutes = -1);
|
||||
void sleep_until(int second = -1, int minute = -1, int hour = -1, int day = -1);
|
||||
WakeUpEvent get_wake_up_event() {return _wake_up_event;}
|
||||
|
||||
// screen management
|
||||
void update(bool blocking=false);
|
||||
static bool is_busy();
|
||||
|
||||
// state
|
||||
bool pressed(Button button);
|
||||
static uint8_t read_shift_register();
|
||||
static bool read_shift_register_bit(uint8_t index);
|
||||
void led(LED led, uint8_t brightness);
|
||||
|
||||
void icon(const uint8_t *data, int sheet_width, int icon_size, int index, int dx, int dy);
|
||||
void image(const uint8_t* data);
|
||||
void image(const uint8_t *data, int w, int h, int x, int y);
|
||||
void image(const uint8_t *data, int stride, int sx, int sy, int dw, int dh, int dx, int dy);
|
||||
};
|
||||
|
||||
}
|
|
@ -32,6 +32,9 @@ namespace pimoroni {
|
|||
void PicoGraphics::frame_convert(PenType type, conversion_callback_func callback) {};
|
||||
void PicoGraphics::sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent) {};
|
||||
|
||||
int PicoGraphics::get_palette_size() {return 0;}
|
||||
RGB* PicoGraphics::get_palette() {return nullptr;}
|
||||
|
||||
void PicoGraphics::set_dimensions(int width, int height) {
|
||||
bounds = clip = {0, 0, width, height};
|
||||
}
|
||||
|
|
|
@ -178,9 +178,6 @@ namespace pimoroni {
|
|||
Rect clip;
|
||||
uint thickness = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef std::function<void(void *data, size_t length)> conversion_callback_func;
|
||||
typedef std::function<RGB565()> next_pixel_func;
|
||||
typedef std::function<RGB888()> next_pixel_func_rgb888;
|
||||
|
@ -233,6 +230,9 @@ namespace pimoroni {
|
|||
virtual void set_pixel_span(const Point &p, uint l) = 0;
|
||||
virtual void set_thickness(uint t) = 0;
|
||||
|
||||
virtual int get_palette_size();
|
||||
virtual RGB* get_palette();
|
||||
|
||||
virtual int create_pen(uint8_t r, uint8_t g, uint8_t b);
|
||||
virtual int create_pen_hsv(float h, float s, float v);
|
||||
virtual int update_pen(uint8_t i, uint8_t r, uint8_t g, uint8_t b);
|
||||
|
@ -344,6 +344,9 @@ namespace pimoroni {
|
|||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
void set_thickness(uint t) override {};
|
||||
|
||||
int get_palette_size() override {return palette_size;};
|
||||
RGB* get_palette() override {return palette;};
|
||||
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
void get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates);
|
||||
|
@ -375,6 +378,9 @@ namespace pimoroni {
|
|||
int create_pen_hsv(float h, float s, float v) override;
|
||||
int reset_pen(uint8_t i) override;
|
||||
|
||||
int get_palette_size() override {return palette_size;};
|
||||
RGB* get_palette() override {return palette;};
|
||||
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
void get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates);
|
||||
|
@ -406,6 +412,9 @@ namespace pimoroni {
|
|||
int create_pen_hsv(float h, float s, float v) override;
|
||||
int reset_pen(uint8_t i) override;
|
||||
|
||||
int get_palette_size() override {return palette_size;};
|
||||
RGB* get_palette() override {return palette;};
|
||||
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
void get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates);
|
||||
|
@ -542,6 +551,9 @@ namespace pimoroni {
|
|||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
|
||||
int get_palette_size() override {return palette_size;};
|
||||
RGB* get_palette() override {return palette;};
|
||||
|
||||
void get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates);
|
||||
void set_pixel_dither(const Point &p, const RGB &c) override;
|
||||
|
||||
|
|
|
@ -149,7 +149,16 @@ MICROPY_EVENT_POLL_HOOK
|
|||
|| current_graphics->pen_type == PicoGraphics::PEN_P4
|
||||
|| current_graphics->pen_type == PicoGraphics::PEN_3BIT
|
||||
|| current_graphics->pen_type == PicoGraphics::PEN_INKY7) {
|
||||
current_graphics->set_pixel_dither({pDraw->x + x, pDraw->y + y}, RGB((RGB565)pDraw->pPixels[i]));
|
||||
if (current_flags & FLAG_NO_DITHER) {
|
||||
int closest = RGB((RGB565)pDraw->pPixels[i]).closest(current_graphics->get_palette(), current_graphics->get_palette_size());
|
||||
if (closest == -1) {
|
||||
closest = 0;
|
||||
}
|
||||
current_graphics->set_pen(closest);
|
||||
current_graphics->pixel({pDraw->x + x, pDraw->y + y});
|
||||
} else {
|
||||
current_graphics->set_pixel_dither({pDraw->x + x, pDraw->y + y}, RGB((RGB565)pDraw->pPixels[i]));
|
||||
}
|
||||
} else {
|
||||
current_graphics->set_pen(pDraw->pPixels[i]);
|
||||
current_graphics->pixel({pDraw->x + x, pDraw->y + y});
|
||||
|
|
Ładowanie…
Reference in New Issue