From e66a2893ed6144ed2357fbb9cd726e4847f3020f Mon Sep 17 00:00:00 2001 From: Martin Budden Date: Mon, 18 Apr 2022 10:10:05 +0100 Subject: [PATCH 1/2] Added a pico display 2.0 Mandelbrot set example. Both pico cores are used: core0 handles the key input and updates the display at low resolution. Core1 updates the display at high resolution. For speed, fixed point arithmetic is used. The main loop also checks for cyles to speed things up. Six color palettes are provided, including 3 HSV, greyscale and black/white. --- examples/CMakeLists.txt | 1 + .../pico_display_2_mandelbrot/CMakeLists.txt | 12 + examples/pico_display_2_mandelbrot/demo.cpp | 335 ++++++++++++++++++ 3 files changed, 348 insertions(+) create mode 100644 examples/pico_display_2_mandelbrot/CMakeLists.txt create mode 100644 examples/pico_display_2_mandelbrot/demo.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 24262ad6..a81efcef 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -27,6 +27,7 @@ add_subdirectory(breakout_oled_128x128) add_subdirectory(pico_display) add_subdirectory(pico_display_2) +add_subdirectory(pico_display_2_mandelbrot) add_subdirectory(pico_unicorn) add_subdirectory(pico_unicorn_plasma) add_subdirectory(pico_scroll) diff --git a/examples/pico_display_2_mandelbrot/CMakeLists.txt b/examples/pico_display_2_mandelbrot/CMakeLists.txt new file mode 100644 index 00000000..6f042e3c --- /dev/null +++ b/examples/pico_display_2_mandelbrot/CMakeLists.txt @@ -0,0 +1,12 @@ +set(OUTPUT_NAME display_2_mandelbrot) + +add_executable( + ${OUTPUT_NAME} + demo.cpp +) + +# Pull in pico libraries that we need +target_link_libraries(${OUTPUT_NAME} pico_stdlib pico_multicore hardware_spi hardware_pwm hardware_dma pico_display_2) + +# create map/bin/hex file etc. +pico_add_extra_outputs(${OUTPUT_NAME}) diff --git a/examples/pico_display_2_mandelbrot/demo.cpp b/examples/pico_display_2_mandelbrot/demo.cpp new file mode 100644 index 00000000..b19a7837 --- /dev/null +++ b/examples/pico_display_2_mandelbrot/demo.cpp @@ -0,0 +1,335 @@ +#define MULTICORE + +#include +#include "pico/stdlib.h" +#if defined(MULTICORE) +#include "pico/multicore.h" +#endif +#include "libraries/pico_display_2/pico_display_2.hpp" + + +using namespace pimoroni; + +typedef int32_t fixed_t; + +class complex_fixed_t { +public: + complex_fixed_t() {} + complex_fixed_t(fixed_t _r, fixed_t _i) : r(_r), i(_i) {} +public: + fixed_t r; + fixed_t i; +}; +inline bool operator==(const complex_fixed_t& lhs, const complex_fixed_t& rhs){ return lhs.r == rhs.r && lhs.i == rhs.i; } + +#define FXD_FRACTIONAL_BITS 25 + +#define FXD_FROM_INT(x) ((x) << FXD_FRACTIONAL_BITS) +static inline fixed_t float_to_fixed(float x) { return static_cast(x * static_cast(1u << FXD_FRACTIONAL_BITS)); } +static inline float fixed_to_float(fixed_t x) { return static_cast(x) / static_cast(1u << FXD_FRACTIONAL_BITS); } +static inline fixed_t fixed_multiply(fixed_t a, fixed_t b) { + const int64_t r = static_cast(a) * static_cast(b); + return static_cast(r >> FXD_FRACTIONAL_BITS); +} +#define FXD_MUL(x, y) fixed_multiply(x, y) + +// PicoDisplay2 is 320 by 240 +#define DISPLAY_WIDTH PicoDisplay2::WIDTH +#define DISPLAY_HEIGHT PicoDisplay2::HEIGHT + +uint16_t g_buffer[DISPLAY_WIDTH * DISPLAY_HEIGHT]; +PicoDisplay2 pico_display(g_buffer); + +class MandelbrotView { +public: + void init(int aSizeX, int aScreenSizeY, uint16_t *aBuffer, int aPalettSize, int aBlockSizeX, int aInterationLimit, int aCore); + void init(const MandelbrotView& aView, int aBlockSizeX, int aInterationLimit, int aCore); + void setRange(fixed_t aFxdRangeR, const complex_fixed_t& aFxdCenter); + void setRange(const MandelbrotView& aView); + void render(void); + void createPalettes(int aPaletteSize); + void nextPalette(void); + inline void start(void) { running = true; } + inline void stop(void) { running = false; } + inline bool isRunning(void) const { return running; } +private: + bool running; + int core; + int screenSizeX; + int screenSizeY; + fixed_t fxdRangeR; + complex_fixed_t fxdCenter; + complex_fixed_t fxdMin; + complex_fixed_t fxdMax; + complex_fixed_t fxdPixel; + int iterationLimit; + int blockSizeX; + uint16_t *pFrameBuffer; + static const uint8_t PALETTE_COUNT = 6; + int paletteIndex; + uint16_t *pPalette; + uint16_t *pPalettes[PALETTE_COUNT]; +}; + +void MandelbrotView::init(int aScreenSizeX, int aScreenSizeY, uint16_t *aBuffer, int aPaletteSize, int aBlockSizeX, int aInterationLimit, int aCore) { + screenSizeX = aScreenSizeX; + screenSizeY = aScreenSizeY; + createPalettes(aPaletteSize); + blockSizeX = aBlockSizeX; + pFrameBuffer = aBuffer; + iterationLimit = aInterationLimit; + core = aCore; + running = true; +} + +void MandelbrotView::init(const MandelbrotView& aView, int aBlockSizeX, int aInterationLimit, int aCore) { + *this = aView; + for (int ii = 0; ii < PALETTE_COUNT; ++ii) { + pPalettes[ii] = aView.pPalettes[ii]; + } + blockSizeX = aBlockSizeX; + iterationLimit = aInterationLimit; + core = aCore; + running = false; +} + +void MandelbrotView::setRange(fixed_t aFxdRangeR, const complex_fixed_t& aFxdCenter) { + fxdRangeR = aFxdRangeR; + fxdCenter = aFxdCenter; + fxdMin.r = aFxdCenter.r - fxdRangeR / 2; + fxdMax.r = aFxdCenter.r + fxdRangeR / 2; + const float screenRatio2 = static_cast(screenSizeY) / static_cast(screenSizeX * 2); + const fixed_t fxdRangeI2 = float_to_fixed(fixed_to_float(fxdRangeR) * screenRatio2); + fxdMin.i = fxdCenter.i - fxdRangeI2; + fxdMax.i = fxdCenter.i + fxdRangeI2; + fxdPixel.r = float_to_fixed(fixed_to_float(fxdRangeR) / screenSizeX); + fxdPixel.i = float_to_fixed(2*fixed_to_float(fxdRangeI2) / screenSizeY); + } + +void MandelbrotView::setRange(const MandelbrotView& aView) { + fxdRangeR = aView.fxdRangeR; + fxdCenter= aView.fxdCenter; + fxdMin = aView.fxdMin; + fxdMax = aView.fxdMax; + fxdPixel = aView.fxdPixel; +} + +void MandelbrotView::render(void) { + const fixed_t fxdMaxZ2 = FXD_FROM_INT(4); + uint16_t *pFrame = pFrameBuffer; + + Pen pen = 0; + + complex_fixed_t fxdC = fxdMin; + for (int screenY = 0; screenY < screenSizeY; ++screenY) { + fxdC.r = fxdMin.r; + for (int screenX = 0; screenX < screenSizeX; screenX += blockSizeX) { + if (!running) { + return; + } + pen = 0; + complex_fixed_t fxdZ = fxdC; + complex_fixed_t fxdZ0 = fxdZ; + int period0 = 0; + + for (int ii = 0; ii < iterationLimit; ++ii) { + const fixed_t fxdZR2 = FXD_MUL(fxdZ.r, fxdZ.r); + const fixed_t fxdZI2 = FXD_MUL(fxdZ.i, fxdZ.i); + if (fxdZR2 + fxdZI2 >= fxdMaxZ2) { + // we are outside the set so set color and break + pen = pPalette[ii]; + break; + } + fxdZ.i = 2 * FXD_MUL(fxdZ.r, fxdZ.i) + fxdC.i; + fxdZ.r = fxdZR2 - fxdZI2 + fxdC.r; + if (fxdZ == fxdZ0) { + // we have a repeating cycle, so we are inside the set + break; + } + if (++period0 > 20) { + period0 = 0; + fxdZ0 = fxdZ; + } + } + + for (int ii = 0; ii < blockSizeX; ++ii) { + *(pFrame + screenX + ii) = pen; + fxdC.r += fxdPixel.r; + } + } + fxdC.i += fxdPixel.i; + pFrame += screenSizeX; + if (core == 1 && (screenY & 0xF) == 0) { + // update core1 view every 16 lines + pico_display.update(); + } + } + pico_display.update(); +} + +// HSV Conversion expects float inputs in the range of 0.0-360.0 for the h channel and 0.0-1.0 for the s and v channels +uint16_t penFromHSV(float h, float s, float v) { + h = fmod(h, 360.0) / 360.0; + const float i = floor(h * 6.0f); + const float f = h * 6.0f - i; + v *= 255.0f; + const uint8_t p = v * (1.0f - s); + const uint8_t q = v * (1.0f - f * s); + const uint8_t t = v * (1.0f - (1.0f - f) * s); + + uint8_t r = 0, g = 0, b = 0; + switch (int(i) % 6) { + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; + } + return pico_display.create_pen(r, g, b); +} + +void MandelbrotView::createPalettes(int aPaletteSize) { + paletteIndex = 2; + for (int ii = 0; ii < PALETTE_COUNT; ++ii) { + pPalettes[ii] = static_cast(malloc(sizeof(uint16_t) * aPaletteSize)); + } + for (int ii = 0; ii < aPaletteSize; ++ii) { + pPalettes[0][ii] = pico_display.create_pen(255 - 255 * ii / aPaletteSize, 255 - 255 * ii / aPaletteSize, 255 - 255 * ii / aPaletteSize); + pPalettes[1][ii] = pico_display.create_pen(255, 255, 255); + pPalettes[2][ii] = penFromHSV(160.0 + 360.0 * static_cast(ii) / aPaletteSize, 0.9, 1.0); + pPalettes[3][ii] = penFromHSV(60.0 + 360.0 * static_cast(ii) / aPaletteSize, 0.9, 1.0); + pPalettes[4][ii] = penFromHSV(360.0 * static_cast(ii) / aPaletteSize, 0.9, 1.0); + pPalettes[5][ii] = pico_display.create_pen(ii % 4 * 64, ii % 8 * 32, ii % 16 * 16); + } + pPalette = pPalettes[paletteIndex]; +} + +void MandelbrotView::nextPalette(void) { + ++paletteIndex; + if (paletteIndex >= PALETTE_COUNT) { + paletteIndex = 0; + } + pPalette = pPalettes[paletteIndex]; +} + +MandelbrotView g_view0; + +#if defined(MULTICORE) +MandelbrotView g_view1; + +// Note no mutual exclusion required for start and stop +static inline void core1_start(void) { + g_view1.start(); +} + +static inline void core1_stop(void) { + g_view1.stop(); +} + +void core1_main(void) { + while (true) { + //uint32_t command = multicore_fifo_pop_blocking(); + while (!g_view1.isRunning()) { + //tight_loop_contents(); + sleep_ms(1); + } + g_view1.render(); + } +} +#endif // MULTICORE + +int main() { + pico_display.init(); + pico_display.set_backlight(100); + pico_display.set_pen(0, 0, 0); + pico_display.clear(); + pico_display.update(); + + const int iterationLimitV0 = 40; + const int iterationLimitV1 = 128; + g_view0.init(DISPLAY_WIDTH, DISPLAY_HEIGHT, g_buffer, iterationLimitV1, 4, iterationLimitV0, 0); + +#if defined(MULTICORE) + g_view1.init(g_view0, 1, iterationLimitV1, 1); + // Launch core1, it won't start rendering until core1_start() is called + multicore_launch_core1(core1_main); +#endif + + const fixed_t fxdInitialRangeR = float_to_fixed(3.2); + const complex_fixed_t fxdInitialCenter(float_to_fixed(-0.75), float_to_fixed(0.0)); + fixed_t fxdRangeR = fxdInitialRangeR; + complex_fixed_t fxdCenter = fxdInitialCenter; + + while (true) { + g_view0.setRange(fxdRangeR, fxdCenter); +#if defined(MULTICORE) + g_view1.setRange(fxdRangeR, fxdCenter); +#endif + pico_display.set_led(64, 0, 0); + + g_view0.render(); + + pico_display.set_led(0, 0, 64); +#if defined(MULTICORE) + core1_start(); +#endif + + pico_display.set_led(0, 0, 0); + + // Loop, waiting for key presses + bool keyPressed = false; + while (keyPressed == false) { + sleep_ms(1); + + if (pico_display.is_pressed(pico_display.A)) { + // Hold A to move left/right + if (pico_display.is_pressed(pico_display.X) && fxdCenter.r > FXD_FROM_INT(-3)) { + fxdCenter.r -= fxdRangeR / 8; + keyPressed = true; + } else if (pico_display.is_pressed(pico_display.Y) && fxdCenter.r < FXD_FROM_INT(3)) { + fxdCenter.r += fxdRangeR / 8; + keyPressed = true; + } else if (pico_display.is_pressed(pico_display.B)) { + // Press A and B together to switch palette + g_view0.nextPalette(); +#if defined(MULTICORE) + g_view1.nextPalette(); +#endif + keyPressed = true; + } + } else if (pico_display.is_pressed(pico_display.B)) { + // Hold B to move up/down + if (pico_display.is_pressed(pico_display.X) && fxdCenter.i > FXD_FROM_INT(-2)) { + fxdCenter.i -= fxdRangeR / 8; + keyPressed = true; + } else if (pico_display.is_pressed(pico_display.Y) && fxdCenter.i < FXD_FROM_INT(2)) { + fxdCenter.i += fxdRangeR / 8; + keyPressed = true; + } + } else { + // Otherwise zoom in/out + if (pico_display.is_pressed(pico_display.X)) { + if (pico_display.is_pressed(pico_display.Y)) { + // Press X and Y together to reset to initial position + fxdRangeR = fxdInitialRangeR; + fxdCenter = fxdInitialCenter; + } else { + fxdRangeR /= 4; + fxdRangeR *= 3; + } + keyPressed = true; + } else if (pico_display.is_pressed(pico_display.Y) && fxdRangeR < FXD_FROM_INT(3)) { + fxdRangeR *= 4; + fxdRangeR /= 3; + keyPressed = true; + } + } + } +#if defined(MULTICORE) + // key pressed, so stop core1 + core1_stop(); +#endif + } + return 0; +} From 8047f29ba6c593429ba200bd9d67a6cf7c826bdf Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Wed, 22 Feb 2023 12:14:47 +0000 Subject: [PATCH 2/2] Port Pico Display 2.0 Mandelbrot to PicoGraphics. Move into Pico Display examples directory and update for PicoGraphics. --- examples/CMakeLists.txt | 1 - examples/pico_display_2/CMakeLists.txt | 2 + .../mandelbrot}/CMakeLists.txt | 2 +- .../mandelbrot}/demo.cpp | 74 +++++++++++-------- 4 files changed, 46 insertions(+), 33 deletions(-) rename examples/{pico_display_2_mandelbrot => pico_display_2/mandelbrot}/CMakeLists.txt (74%) rename examples/{pico_display_2_mandelbrot => pico_display_2/mandelbrot}/demo.cpp (84%) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a81efcef..24262ad6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -27,7 +27,6 @@ add_subdirectory(breakout_oled_128x128) add_subdirectory(pico_display) add_subdirectory(pico_display_2) -add_subdirectory(pico_display_2_mandelbrot) add_subdirectory(pico_unicorn) add_subdirectory(pico_unicorn_plasma) add_subdirectory(pico_scroll) diff --git a/examples/pico_display_2/CMakeLists.txt b/examples/pico_display_2/CMakeLists.txt index 0dfd3438..d40b117e 100644 --- a/examples/pico_display_2/CMakeLists.txt +++ b/examples/pico_display_2/CMakeLists.txt @@ -1,3 +1,5 @@ +add_subdirectory(mandelbrot) + set(OUTPUT_NAME pico_display2_demo) add_executable( diff --git a/examples/pico_display_2_mandelbrot/CMakeLists.txt b/examples/pico_display_2/mandelbrot/CMakeLists.txt similarity index 74% rename from examples/pico_display_2_mandelbrot/CMakeLists.txt rename to examples/pico_display_2/mandelbrot/CMakeLists.txt index 6f042e3c..af46358b 100644 --- a/examples/pico_display_2_mandelbrot/CMakeLists.txt +++ b/examples/pico_display_2/mandelbrot/CMakeLists.txt @@ -6,7 +6,7 @@ add_executable( ) # Pull in pico libraries that we need -target_link_libraries(${OUTPUT_NAME} pico_stdlib pico_multicore hardware_spi hardware_pwm hardware_dma pico_display_2) +target_link_libraries(${OUTPUT_NAME} pico_stdlib pico_multicore hardware_spi hardware_pwm hardware_dma rgbled button pico_display_2 st7789 pico_graphics) # create map/bin/hex file etc. pico_add_extra_outputs(${OUTPUT_NAME}) diff --git a/examples/pico_display_2_mandelbrot/demo.cpp b/examples/pico_display_2/mandelbrot/demo.cpp similarity index 84% rename from examples/pico_display_2_mandelbrot/demo.cpp rename to examples/pico_display_2/mandelbrot/demo.cpp index b19a7837..79817a98 100644 --- a/examples/pico_display_2_mandelbrot/demo.cpp +++ b/examples/pico_display_2/mandelbrot/demo.cpp @@ -5,11 +5,30 @@ #if defined(MULTICORE) #include "pico/multicore.h" #endif + #include "libraries/pico_display_2/pico_display_2.hpp" +#include "drivers/st7789/st7789.hpp" +#include "libraries/pico_graphics/pico_graphics.hpp" +#include "rgbled.hpp" +#include "button.hpp" using namespace pimoroni; +// PicoDisplay2 is 320 by 240 +#define DISPLAY_WIDTH PicoDisplay2::WIDTH +#define DISPLAY_HEIGHT PicoDisplay2::HEIGHT + +ST7789 st7789(DISPLAY_WIDTH, DISPLAY_HEIGHT, ROTATE_0, false, get_spi_pins(BG_SPI_FRONT)); +PicoGraphics_PenRGB565 graphics(st7789.width, st7789.height, nullptr); + +RGBLED led(PicoDisplay2::LED_R, PicoDisplay2::LED_G, PicoDisplay2::LED_B); + +Button button_a(PicoDisplay2::A); +Button button_b(PicoDisplay2::B); +Button button_x(PicoDisplay2::X); +Button button_y(PicoDisplay2::Y); + typedef int32_t fixed_t; class complex_fixed_t { @@ -33,12 +52,6 @@ static inline fixed_t fixed_multiply(fixed_t a, fixed_t b) { } #define FXD_MUL(x, y) fixed_multiply(x, y) -// PicoDisplay2 is 320 by 240 -#define DISPLAY_WIDTH PicoDisplay2::WIDTH -#define DISPLAY_HEIGHT PicoDisplay2::HEIGHT - -uint16_t g_buffer[DISPLAY_WIDTH * DISPLAY_HEIGHT]; -PicoDisplay2 pico_display(g_buffer); class MandelbrotView { public: @@ -161,10 +174,10 @@ void MandelbrotView::render(void) { pFrame += screenSizeX; if (core == 1 && (screenY & 0xF) == 0) { // update core1 view every 16 lines - pico_display.update(); + st7789.update(&graphics); } } - pico_display.update(); + st7789.update(&graphics); } // HSV Conversion expects float inputs in the range of 0.0-360.0 for the h channel and 0.0-1.0 for the s and v channels @@ -186,7 +199,7 @@ uint16_t penFromHSV(float h, float s, float v) { case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; } - return pico_display.create_pen(r, g, b); + return graphics.create_pen(r, g, b); } void MandelbrotView::createPalettes(int aPaletteSize) { @@ -195,12 +208,12 @@ void MandelbrotView::createPalettes(int aPaletteSize) { pPalettes[ii] = static_cast(malloc(sizeof(uint16_t) * aPaletteSize)); } for (int ii = 0; ii < aPaletteSize; ++ii) { - pPalettes[0][ii] = pico_display.create_pen(255 - 255 * ii / aPaletteSize, 255 - 255 * ii / aPaletteSize, 255 - 255 * ii / aPaletteSize); - pPalettes[1][ii] = pico_display.create_pen(255, 255, 255); + pPalettes[0][ii] = graphics.create_pen(255 - 255 * ii / aPaletteSize, 255 - 255 * ii / aPaletteSize, 255 - 255 * ii / aPaletteSize); + pPalettes[1][ii] = graphics.create_pen(255, 255, 255); pPalettes[2][ii] = penFromHSV(160.0 + 360.0 * static_cast(ii) / aPaletteSize, 0.9, 1.0); pPalettes[3][ii] = penFromHSV(60.0 + 360.0 * static_cast(ii) / aPaletteSize, 0.9, 1.0); pPalettes[4][ii] = penFromHSV(360.0 * static_cast(ii) / aPaletteSize, 0.9, 1.0); - pPalettes[5][ii] = pico_display.create_pen(ii % 4 * 64, ii % 8 * 32, ii % 16 * 16); + pPalettes[5][ii] = graphics.create_pen(ii % 4 * 64, ii % 8 * 32, ii % 16 * 16); } pPalette = pPalettes[paletteIndex]; } @@ -240,15 +253,14 @@ void core1_main(void) { #endif // MULTICORE int main() { - pico_display.init(); - pico_display.set_backlight(100); - pico_display.set_pen(0, 0, 0); - pico_display.clear(); - pico_display.update(); + st7789.set_backlight(100); + graphics.set_pen(0, 0, 0); + graphics.clear(); + st7789.update(&graphics); const int iterationLimitV0 = 40; const int iterationLimitV1 = 128; - g_view0.init(DISPLAY_WIDTH, DISPLAY_HEIGHT, g_buffer, iterationLimitV1, 4, iterationLimitV0, 0); + g_view0.init(DISPLAY_WIDTH, DISPLAY_HEIGHT, (uint16_t *)graphics.frame_buffer, iterationLimitV1, 4, iterationLimitV0, 0); #if defined(MULTICORE) g_view1.init(g_view0, 1, iterationLimitV1, 1); @@ -266,31 +278,31 @@ int main() { #if defined(MULTICORE) g_view1.setRange(fxdRangeR, fxdCenter); #endif - pico_display.set_led(64, 0, 0); + led.set_rgb(64, 0, 0); g_view0.render(); - pico_display.set_led(0, 0, 64); + led.set_rgb(0, 0, 64); #if defined(MULTICORE) core1_start(); #endif - pico_display.set_led(0, 0, 0); + led.set_rgb(0, 0, 0); // Loop, waiting for key presses bool keyPressed = false; while (keyPressed == false) { sleep_ms(1); - if (pico_display.is_pressed(pico_display.A)) { + if (button_a.raw()) { // Hold A to move left/right - if (pico_display.is_pressed(pico_display.X) && fxdCenter.r > FXD_FROM_INT(-3)) { + if (button_x.read() && fxdCenter.r > FXD_FROM_INT(-3)) { fxdCenter.r -= fxdRangeR / 8; keyPressed = true; - } else if (pico_display.is_pressed(pico_display.Y) && fxdCenter.r < FXD_FROM_INT(3)) { + } else if (button_y.read() && fxdCenter.r < FXD_FROM_INT(3)) { fxdCenter.r += fxdRangeR / 8; keyPressed = true; - } else if (pico_display.is_pressed(pico_display.B)) { + } else if (button_b.read()) { // Press A and B together to switch palette g_view0.nextPalette(); #if defined(MULTICORE) @@ -298,19 +310,19 @@ int main() { #endif keyPressed = true; } - } else if (pico_display.is_pressed(pico_display.B)) { + } else if (button_b.raw()) { // Hold B to move up/down - if (pico_display.is_pressed(pico_display.X) && fxdCenter.i > FXD_FROM_INT(-2)) { + if (button_x.read() && fxdCenter.i > FXD_FROM_INT(-2)) { fxdCenter.i -= fxdRangeR / 8; keyPressed = true; - } else if (pico_display.is_pressed(pico_display.Y) && fxdCenter.i < FXD_FROM_INT(2)) { + } else if (button_y.read() && fxdCenter.i < FXD_FROM_INT(2)) { fxdCenter.i += fxdRangeR / 8; keyPressed = true; } } else { // Otherwise zoom in/out - if (pico_display.is_pressed(pico_display.X)) { - if (pico_display.is_pressed(pico_display.Y)) { + if (button_x.read()) { + if (button_y.read()) { // Press X and Y together to reset to initial position fxdRangeR = fxdInitialRangeR; fxdCenter = fxdInitialCenter; @@ -319,7 +331,7 @@ int main() { fxdRangeR *= 3; } keyPressed = true; - } else if (pico_display.is_pressed(pico_display.Y) && fxdRangeR < FXD_FROM_INT(3)) { + } else if (button_y.read() && fxdRangeR < FXD_FROM_INT(3)) { fxdRangeR *= 4; fxdRangeR /= 3; keyPressed = true;