From 2a34f955ca83973388bca5859c11e490efaf4d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 11 Mar 2019 15:25:24 +0100 Subject: [PATCH] [python/turtle] Fix some turtle jumps There was a drawing glitch for instance when doing goto(100,100). It was due to the tutle mileage being overflowed. --- python/port/mod/turtle/turtle.cpp | 25 +++++++++---------------- python/port/mod/turtle/turtle.h | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/python/port/mod/turtle/turtle.cpp b/python/port/mod/turtle/turtle.cpp index 20e9c15cd..0b7dcad89 100644 --- a/python/port/mod/turtle/turtle.cpp +++ b/python/port/mod/turtle/turtle.cpp @@ -335,24 +335,11 @@ bool Turtle::draw(bool force) { m_drawn = true; } - /* We sleep every time the turtle walks a mileageLimit amount, to allow user - * interruptions. The length of each sleep is determined by the speed of the - * turtle. - * With emscripten, sleep gives control to the web browser, which decides when - * to return from sleep: this makes the turtle significantly slower on the web - * emulator than on the calculator. We thus decided to sleep less often on the - * emscripten platform. */ -#if __EMSCRIPTEN__ - constexpr KDCoordinate mileageLimit = 10000; -#else - constexpr KDCoordinate mileageLimit = 1000; -#endif - - if (m_mileage > mileageLimit) { + if (m_mileage > k_mileageLimit) { if (micropython_port_interruptible_msleep(1 + (m_speed == 0 ? 0 : 3 * (k_maxSpeed - m_speed)))) { return true; } - m_mileage -= mileageLimit; + m_mileage -= k_mileageLimit; } return false; } @@ -360,6 +347,7 @@ bool Turtle::draw(bool force) { bool Turtle::dot(mp_float_t x, mp_float_t y) { MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox(); + // Draw the dot if the pen is down if (m_penDown && hasDotBuffers()) { KDContext * ctx = KDIonContext::sharedContext(); KDRect rect( @@ -369,7 +357,12 @@ bool Turtle::dot(mp_float_t x, mp_float_t y) { ctx->blendRectWithMask(rect, m_color, m_dotMask, m_dotWorkingPixelBuffer); } - m_mileage += sqrt((x - m_x) * (x - m_x) + (y - m_y) * (y - m_y)) * 1000; + /* Increase the turtle's mileage. We need to make sure the mileage is not + * overflowed, otherwise we might skip some msleeps in draw. */ + uint16_t additionalMileage = sqrt((x - m_x) * (x - m_x) + (y - m_y) * (y - m_y)) * 1000; + m_mileage = ((m_mileage > k_mileageLimit) + && ((m_mileage + additionalMileage) < k_mileageLimit)) ? + k_mileageLimit + 1 : m_mileage + additionalMileage; m_x = x; m_y = y; diff --git a/python/port/mod/turtle/turtle.h b/python/port/mod/turtle/turtle.h index 2b9d83b9c..87aa58e8f 100644 --- a/python/port/mod/turtle/turtle.h +++ b/python/port/mod/turtle/turtle.h @@ -154,7 +154,21 @@ private: uint8_t m_speed; // Speed is between 0 and 10 KDCoordinate m_penSize; - KDCoordinate m_mileage; + + /* We sleep every time the turtle walks a mileageLimit amount, to allow user + * interruptions. The length of each sleep is determined by the speed of the + * turtle. + * With emscripten, sleep gives control to the web browser, which decides when + * to return from sleep: this makes the turtle significantly slower on the web + * emulator than on the calculator. We thus decided to sleep less often on the + * emscripten platform. */ +#if __EMSCRIPTEN__ + static constexpr uint16_t k_mileageLimit = 10000; +#else + static constexpr uint16_t k_mileageLimit = 1000; +#endif + + uint16_t m_mileage; bool m_drawn; };