summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--atmel-samd/Makefile3
-rw-r--r--shared-bindings/_stage/Layer.c130
-rw-r--r--shared-bindings/_stage/Layer.h34
-rw-r--r--shared-bindings/_stage/Text.c109
-rw-r--r--shared-bindings/_stage/Text.h34
-rw-r--r--shared-bindings/_stage/__init__.c97
-rw-r--r--shared-bindings/_stage/__init__.h32
-rw-r--r--shared-module/_stage/Layer.c105
-rw-r--r--shared-module/_stage/Layer.h48
-rw-r--r--shared-module/_stage/Text.c67
-rw-r--r--shared-module/_stage/Text.h46
-rw-r--r--shared-module/_stage/__init__.c76
-rw-r--r--shared-module/_stage/__init__.h42
13 files changed, 823 insertions, 0 deletions
diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile
index 4a45106db..f6c183ba9 100644
--- a/atmel-samd/Makefile
+++ b/atmel-samd/Makefile
@@ -333,6 +333,9 @@ SRC_SHARED_MODULE = \
os/__init__.c \
random/__init__.c \
storage/__init__.c \
+ _stage/__init__.c \
+ _stage/Layer.c \
+ _stage/Text.c \
uheap/__init__.c \
ustack/__init__.c
diff --git a/shared-bindings/_stage/Layer.c b/shared-bindings/_stage/Layer.c
new file mode 100644
index 000000000..3e615c497
--- /dev/null
+++ b/shared-bindings/_stage/Layer.c
@@ -0,0 +1,130 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <py/runtime.h>
+
+#include "__init__.h"
+#include "Layer.h"
+
+//| .. currentmodule:: _stage
+//|
+//| :class:`Layer` -- Keep information about a single layer of graphics
+//| ===================================================================
+//|
+//| .. class:: Layer(width, height, graphic, palette, [grid])
+//|
+//| Keep internal information about a layer of graphics (either a
+//| ``Grid`` or a ``Sprite``) in a format suitable for fast rendering
+//| with the ``render()`` function.
+//|
+//| :param int width: The width of the grid in tiles, or 1 for sprites.
+//| :param int height: The height of the grid in tiles, or 1 for sprites.
+//| :param bytearray graphic: The graphic data of the tiles.
+//| :param bytearray palette: The color palette to be used.
+//| :param bytearray grid: The contents of the grid map.
+//|
+//| This class is intended for internal use in the ``stage`` library and
+//| it shouldn't be used on its own.
+//|
+STATIC mp_obj_t layer_make_new(const mp_obj_type_t *type, size_t n_args,
+ size_t n_kw, const mp_obj_t *args) {
+ mp_arg_check_num(n_args, n_kw, 4, 5, false);
+
+ layer_obj_t *self = m_new_obj(layer_obj_t);
+ self->base.type = type;
+
+ self->width = mp_obj_get_int(args[0]);
+ self->height = mp_obj_get_int(args[1]);
+ self->x = 0;
+ self->y = 0;
+ self->frame = 0;
+ self->rotation = false;
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
+ self->graphic = bufinfo.buf;
+ if (bufinfo.len != 2048) {
+ mp_raise_ValueError("graphic must be 2048 bytes long");
+ }
+
+ mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ);
+ self->palette = bufinfo.buf;
+ if (bufinfo.len != 32) {
+ mp_raise_ValueError("palette must be 32 bytes long");
+ }
+
+ if (n_args > 4) {
+ mp_get_buffer_raise(args[4], &bufinfo, MP_BUFFER_READ);
+ self->map = bufinfo.buf;
+ if (bufinfo.len < (self->width * self->height) / 2) {
+ mp_raise_ValueError("map buffer too small");
+ }
+ } else {
+ self-> map = NULL;
+ }
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: move(x, y)
+//|
+//| Set the offset of the layer to the specified values.
+//|
+STATIC mp_obj_t layer_move(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) {
+ layer_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ self->x = mp_obj_get_int(x_in);
+ self->y = mp_obj_get_int(y_in);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(layer_move_obj, layer_move);
+
+//| .. method:: frame(frame, rotation)
+//|
+//| Set the animation frame of the sprite, and optionally rotation its
+//| graphic.
+//|
+STATIC mp_obj_t layer_frame(mp_obj_t self_in, mp_obj_t frame_in,
+ mp_obj_t rotation_in) {
+ layer_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ self->frame = mp_obj_get_int(frame_in);
+ self->rotation = mp_obj_get_int(rotation_in);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(layer_frame_obj, layer_frame);
+
+
+STATIC const mp_rom_map_elem_t layer_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_move), MP_ROM_PTR(&layer_move_obj) },
+ { MP_ROM_QSTR(MP_QSTR_frame), MP_ROM_PTR(&layer_frame_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(layer_locals_dict, layer_locals_dict_table);
+
+const mp_obj_type_t mp_type_layer = {
+ { &mp_type_type },
+ .name = MP_QSTR_Layer,
+ .make_new = layer_make_new,
+ .locals_dict = (mp_obj_dict_t*)&layer_locals_dict,
+};
diff --git a/shared-bindings/_stage/Layer.h b/shared-bindings/_stage/Layer.h
new file mode 100644
index 000000000..6d15dfb28
--- /dev/null
+++ b/shared-bindings/_stage/Layer.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED__STAGE_LAYER_H
+#define MICROPY_INCLUDED__STAGE_LAYER_H
+
+#include "shared-module/_stage/Layer.h"
+
+extern const mp_obj_type_t mp_type_layer;
+
+#endif // MICROPY_INCLUDED__STAGE_LAYER
diff --git a/shared-bindings/_stage/Text.c b/shared-bindings/_stage/Text.c
new file mode 100644
index 000000000..c62d22afe
--- /dev/null
+++ b/shared-bindings/_stage/Text.c
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <py/runtime.h>
+
+#include "__init__.h"
+#include "Text.h"
+
+//| .. currentmodule:: _stage
+//|
+//| :class:`Text` -- Keep information about a single text of text
+//| ==============================================================
+//|
+//| .. class:: Text(width, height, font, palette, chars)
+//|
+//| Keep internal information about a text of text
+//| in a format suitable for fast rendering
+//| with the ``render()`` function.
+//|
+//| :param int width: The width of the grid in tiles, or 1 for sprites.
+//| :param int height: The height of the grid in tiles, or 1 for sprites.
+//| :param bytearray font: The font data of the characters.
+//| :param bytearray palette: The color palette to be used.
+//| :param bytearray chars: The contents of the character grid.
+//|
+//| This class is intended for internal use in the ``stage`` library and
+//| it shouldn't be used on its own.
+//|
+STATIC mp_obj_t text_make_new(const mp_obj_type_t *type, size_t n_args,
+ size_t n_kw, const mp_obj_t *args) {
+ mp_arg_check_num(n_args, n_kw, 5, 5, false);
+
+ text_obj_t *self = m_new_obj(text_obj_t);
+ self->base.type = type;
+
+ self->width = mp_obj_get_int(args[0]);
+ self->height = mp_obj_get_int(args[1]);
+ self->x = 0;
+ self->y = 0;
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
+ self->font = bufinfo.buf;
+ if (bufinfo.len != 2048) {
+ mp_raise_ValueError("font must be 2048 bytes long");
+ }
+
+ mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ);
+ self->palette = bufinfo.buf;
+ if (bufinfo.len != 32) {
+ mp_raise_ValueError("palette must be 32 bytes long");
+ }
+
+ mp_get_buffer_raise(args[4], &bufinfo, MP_BUFFER_READ);
+ self->chars = bufinfo.buf;
+ if (bufinfo.len < self->width * self->height) {
+ mp_raise_ValueError("chars buffer too small");
+ }
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: move(x, y)
+//|
+//| Set the offset of the text to the specified values.
+//|
+STATIC mp_obj_t text_move(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) {
+ text_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ self->x = mp_obj_get_int(x_in);
+ self->y = mp_obj_get_int(y_in);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(text_move_obj, text_move);
+
+
+STATIC const mp_rom_map_elem_t text_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_move), MP_ROM_PTR(&text_move_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(text_locals_dict, text_locals_dict_table);
+
+const mp_obj_type_t mp_type_text = {
+ { &mp_type_type },
+ .name = MP_QSTR_Text,
+ .make_new = text_make_new,
+ .locals_dict = (mp_obj_dict_t*)&text_locals_dict,
+};
diff --git a/shared-bindings/_stage/Text.h b/shared-bindings/_stage/Text.h
new file mode 100644
index 000000000..77de62a11
--- /dev/null
+++ b/shared-bindings/_stage/Text.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED__STAGE_TEXT_H
+#define MICROPY_INCLUDED__STAGE_TEXT_H
+
+#include "shared-module/_stage/Text.h"
+
+extern const mp_obj_type_t mp_type_text;
+
+#endif // MICROPY_INCLUDED__STAGE_TEXT
diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c
new file mode 100644
index 000000000..16e0b58d9
--- /dev/null
+++ b/shared-bindings/_stage/__init__.c
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "__init__.h"
+#include "py/mperrno.h"
+#include "py/runtime.h"
+#include "shared-bindings/busio/SPI.h"
+#include "shared-module/_stage/__init__.h"
+#include "Layer.h"
+#include "Text.h"
+
+//| .. currentmodule:: _stage
+//|
+//| .. function:: render(x0, y0, x1, y1, layers, buffer, spi)
+//|
+//| Render and send to the display a fragment of the screen.
+//|
+//| :param int x0: Left edge of the fragment.
+//| :param int y0: Top edge of the fragment.
+//| :param int x1: Right edge of the fragment.
+//| :param int y1: Bottom edge of the fragment.
+//| :param list layers: A list of the `Layer` objects.
+//| :param bytearray buffer: A buffer to use for rendering.
+//| :param SPI spi: The SPI device to use.
+//|
+//| Note that this function only sends the raw pixel data. Setting up
+//| the display for receiving it and handling the chip-select and
+//| data-command pins has to be done outside of it.
+//| There are also no sanity checks, outside of the basic overflow
+//| checking. The caller is responsible for making the passed parameters
+//| valid.
+//|
+//| This function is intended for internal use in the ``stage`` library
+//| and all the necessary checks are performed there.
+STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) {
+ uint8_t x0 = mp_obj_get_int(args[0]);
+ uint8_t y0 = mp_obj_get_int(args[1]);
+ uint8_t x1 = mp_obj_get_int(args[2]);
+ uint8_t y1 = mp_obj_get_int(args[3]);
+
+ size_t layers_size = 0;
+ mp_obj_t *layers;
+ mp_obj_get_array(args[4], &layers_size, &layers);
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[5], &bufinfo, MP_BUFFER_WRITE);
+ uint16_t *buffer = bufinfo.buf;
+ size_t buffer_size = bufinfo.len / 2; // 16-bit indexing
+
+ busio_spi_obj_t *spi = MP_OBJ_TO_PTR(args[6]);
+
+ if (!render_stage(x0, y0, x1, y1, layers, layers_size,
+ buffer, buffer_size, spi)) {
+ mp_raise_OSError(MP_EIO);
+ }
+
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stage_render_obj, 7, 7, stage_render);
+
+
+STATIC const mp_rom_map_elem_t stage_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__stage) },
+ { MP_ROM_QSTR(MP_QSTR_Layer), MP_ROM_PTR(&mp_type_layer) },
+ { MP_ROM_QSTR(MP_QSTR_Text), MP_ROM_PTR(&mp_type_text) },
+ { MP_ROM_QSTR(MP_QSTR_render), MP_ROM_PTR(&stage_render_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(stage_module_globals, stage_module_globals_table);
+
+const mp_obj_module_t stage_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&stage_module_globals,
+};
diff --git a/shared-bindings/_stage/__init__.h b/shared-bindings/_stage/__init__.h
new file mode 100644
index 000000000..2df81cb3b
--- /dev/null
+++ b/shared-bindings/_stage/__init__.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED__STAGE_H
+#define MICROPY_INCLUDED__STAGE_H
+
+#include "shared-module/_stage/__init__.h"
+
+#endif // MICROPY_INCLUDED__STAGE
diff --git a/shared-module/_stage/Layer.c b/shared-module/_stage/Layer.c
new file mode 100644
index 000000000..3315ac69e
--- /dev/null
+++ b/shared-module/_stage/Layer.c
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "Layer.h"
+#include "__init__.h"
+
+
+// Get the color of the pixel on the layer.
+uint16_t get_layer_pixel(layer_obj_t *layer, int16_t x, uint16_t y) {
+
+ // Shift by the layer's position offset.
+ x -= layer->x;
+ y -= layer->y;
+
+ // Bounds check.
+ if ((x < 0) || (x >= layer->width << 4) ||
+ (y < 0) || (y >= layer->height << 4)) {
+ return TRANSPARENT;
+ }
+
+ // Get the tile from the grid location or from sprite frame.
+ uint8_t frame = layer->frame;
+ if (layer->map) {
+ uint8_t tx = x >> 4;
+ uint8_t ty = y >> 4;
+
+ frame = layer->map[(tx * layer->width + ty) >> 1];
+ if (ty & 0x01) {
+ frame &= 0x0f;
+ } else {
+ frame >>= 4;
+ }
+ }
+
+ // Get the position within the tile.
+ x &= 0x0f;
+ y &= 0x0f;
+
+ // Rotate the image.
+ uint8_t tx = x; // Temporary variable for swapping.
+ switch (layer->rotation) {
+ case 1: // 90 degrees clockwise
+ x = 15 - y;
+ y = tx;
+ break;
+ case 2: // 180 degrees
+ x = 15 - tx;
+ y = 15 - y;
+ break;
+ case 3: // 90 degrees counter-clockwise
+ x = y;
+ y = 15 - tx;
+ break;
+ case 4: // 0 degrees, mirrored
+ y = 15 - y;
+ break;
+ case 5: // 90 degrees clockwise, mirrored
+ x = y;
+ y = tx;
+ break;
+ case 6: // 180 degrees, mirrored
+ x = 15 - tx;
+ break;
+ case 7: // 90 degrees counter-clockwise, mirrored
+ x = 15 - y;
+ y = 15 - tx;
+ break;
+ default: // 0 degrees
+ break;
+ }
+
+ // Get the value of the pixel.
+ uint8_t pixel = layer->graphic[(frame << 7) + (x << 3) + (y >> 1)];
+ if (y & 0x01) {
+ pixel &= 0x0f;
+ } else {
+ pixel >>= 4;
+ }
+
+ // Convert to 16-bit color using the palette.
+ return layer->palette[pixel << 1] | layer->palette[(pixel << 1) + 1] << 8;
+}
diff --git a/shared-module/_stage/Layer.h b/shared-module/_stage/Layer.h
new file mode 100644
index 000000000..c46f71349
--- /dev/null
+++ b/shared-module/_stage/Layer.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE__STAGE_LAYER_H
+#define MICROPY_INCLUDED_SHARED_MODULE__STAGE_LAYER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t *map;
+ uint8_t *graphic;
+ uint8_t *palette;
+ int16_t x, y;
+ uint8_t width, height;
+ uint8_t frame;
+ uint8_t rotation;
+} layer_obj_t;
+
+uint16_t get_layer_pixel(layer_obj_t *layer, int16_t x, uint16_t y);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE_LAYER
diff --git a/shared-module/_stage/Text.c b/shared-module/_stage/Text.c
new file mode 100644
index 000000000..6c451bf38
--- /dev/null
+++ b/shared-module/_stage/Text.c
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "Text.h"
+#include "__init__.h"
+
+
+// Get the color of the pixel on the text.
+uint16_t get_text_pixel(text_obj_t *text, int16_t x, uint16_t y) {
+
+ // Shift by the text's position offset.
+ x -= text->x;
+ y -= text->y;
+
+ // Bounds check.
+ if ((x < 0) || (x >= text->width << 3) ||
+ (y < 0) || (y >= text->height << 3)) {
+ return TRANSPARENT;
+ }
+
+ // Get the tile from the grid location or from sprite frame.
+ uint8_t tx = x >> 3;
+ uint8_t ty = y >> 3;
+ uint8_t c = text->chars[ty * text->width + tx];
+ uint8_t color_offset = 0;
+ if (c & 0x80) {
+ color_offset = 4;
+ }
+ c &= 0x7f;
+ if (!c) {
+ return TRANSPARENT;
+ }
+
+ // Get the position within the char.
+ x &= 0x07;
+ y &= 0x07;
+
+ // Get the value of the pixel.
+ uint8_t pixel = text->font[(c << 4) + (x << 1) + (y >> 2)];
+ pixel = ((pixel >> ((y & 0x03) << 1)) & 0x03) + color_offset;
+
+ // Convert to 16-bit color using the palette.
+ return text->palette[pixel << 1] | text->palette[(pixel << 1) + 1] << 8;
+}
diff --git a/shared-module/_stage/Text.h b/shared-module/_stage/Text.h
new file mode 100644
index 000000000..bc111e49c
--- /dev/null
+++ b/shared-module/_stage/Text.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE__STAGE_TEXT_H
+#define MICROPY_INCLUDED_SHARED_MODULE__STAGE_TEXT_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t *chars;
+ uint8_t *font;
+ uint8_t *palette;
+ int16_t x, y;
+ uint8_t width, height;
+} text_obj_t;
+
+uint16_t get_text_pixel(text_obj_t *text, int16_t x, uint16_t y);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE_TEXT
diff --git a/shared-module/_stage/__init__.c b/shared-module/_stage/__init__.c
new file mode 100644
index 000000000..1931b8940
--- /dev/null
+++ b/shared-module/_stage/__init__.c
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "Layer.h"
+#include "Text.h"
+#include "__init__.h"
+#include "shared-bindings/_stage/Layer.h"
+#include "shared-bindings/_stage/Text.h"
+
+
+bool render_stage(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
+ mp_obj_t *layers, size_t layers_size,
+ uint16_t *buffer, size_t buffer_size,
+ busio_spi_obj_t *spi) {
+
+ // TODO(deshipu): Do a collision check of each layer with the
+ // rectangle, and only process the layers that overlap with it.
+
+ size_t index = 0;
+ for (uint8_t y = y0; y < y1; ++y) {
+ for (uint8_t x = x0; x < x1; ++x) {
+ for (size_t layer = 0; layer < layers_size; ++layer) {
+ uint16_t c = TRANSPARENT;
+ layer_obj_t *obj = MP_OBJ_TO_PTR(layers[layer]);
+ if (obj->base.type == &mp_type_layer) {
+ c = get_layer_pixel(obj, x, y);
+ } else if (obj->base.type == &mp_type_text) {
+ c = get_text_pixel((text_obj_t *)obj, x, y);
+ }
+ if (c != TRANSPARENT) {
+ buffer[index] = c;
+ break;
+ }
+ }
+ index += 1;
+ // The buffer is full, send it.
+ if (index >= buffer_size) {
+ if (!common_hal_busio_spi_write(spi,
+ ((uint8_t*)buffer), buffer_size * 2)) {
+ return false;
+ }
+ index = 0;
+ }
+ }
+ }
+ // Send the remaining data.
+ if (index) {
+ if (!common_hal_busio_spi_write(spi, ((uint8_t*)buffer), index * 2)) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/shared-module/_stage/__init__.h b/shared-module/_stage/__init__.h
new file mode 100644
index 000000000..326c72559
--- /dev/null
+++ b/shared-module/_stage/__init__.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Radomir Dopieralski
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE__STAGE_H
+#define MICROPY_INCLUDED_SHARED_MODULE__STAGE_H
+
+#include "shared-bindings/busio/SPI.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "py/obj.h"
+
+#define TRANSPARENT (0x1ff8)
+
+bool render_stage(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
+ mp_obj_t *layers, size_t layers_size,
+ uint16_t *buffer, size_t buffer_size,
+ busio_spi_obj_t *spi);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE