Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tile palette mapper module and class #10113

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ"
LONGINT_IMPL = MPZ

CIRCUITPY_JPEGIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ CIRCUITPY_PS2IO = 1
CIRCUITPY_JPEGIO = 0
CIRCUITPY_SPITARGET = 0
CIRCUITPY_SYNTHIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
1 change: 1 addition & 0 deletions ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ LONGINT_IMPL = MPZ
CIRCUITPY_SYNTHIO = 0
CIRCUITPY_JPEGIO = 0
CIRCUITPY_SPITARGET = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C, W25Q16JVxQ"
LONGINT_IMPL = MPZ

CIRCUITPY_RAINBOWIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ CHIP_FAMILY = samd21
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICES = "S25FL064L"
LONGINT_IMPL = MPZ

CIRCUITPY_TILEPALETTEMAPPER = 0
2 changes: 2 additions & 0 deletions ports/atmel-samd/boards/huntercat_nfc/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ CHIP_FAMILY = samd21
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ"
LONGINT_IMPL = MPZ

CIRCUITPY_TILEPALETTEMAPPER = 0
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANG_APA102 = 1

CIRCUITPY_PULSEIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ CIRCUITPY_CODEOP = 0
CIRCUITPY_FLOPPYIO = 0
CIRCUITPY_GIFIO = 0
CIRCUITPY_JPEGIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0

CIRCUITPY_BITBANG_APA102 = 1

Expand Down
1 change: 1 addition & 0 deletions ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ LONGINT_IMPL = MPZ

CIRCUITPY_CODEOP = 0
CIRCUITPY_RAINBOWIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
1 change: 1 addition & 0 deletions ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ CIRCUITPY_KEYPAD = 1
CIRCUITPY_SYNTHIO = 0
CIRCUITPY_JPEGIO = 0
CIRCUITPY_FLOPPYIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
1 change: 1 addition & 0 deletions ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ CIRCUITPY_PULSEIO = 0
CIRCUITPY_RGBMATRIX = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
CIRCUITPY_ULAB = 0
CIRCUITPY_USB_HID = 0
CIRCUITPY_USB_MIDI = 0
Expand Down
2 changes: 2 additions & 0 deletions ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ CHIP_FAMILY = samd21
LONGINT_IMPL = MPZ
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICES = "GD25Q16C,W25Q16JVxQ,W25Q32FV"

CIRCUITPY_TILEPALETTEMAPPER = 0
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ LONGINT_IMPL = MPZ
CIRCUITPY_JPEGIO = 0
CIRCUITPY_SPITARGET = 0
CIRCUITPY_SYNTHIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
2 changes: 2 additions & 0 deletions ports/atmel-samd/boards/snekboard/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ CHIP_FAMILY = samd21
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ"
LONGINT_IMPL = MPZ

CIRCUITPY_TILEPALETTEMAPPER = 0
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ LONGINT_IMPL = MPZ

CIRCUITPY_CODEOP = 0
CIRCUITPY_RAINBOWIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ EXTERNAL_FLASH_DEVICES = W25Q32BV
LONGINT_IMPL = MPZ

CIRCUITPY_CODEOP = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
1 change: 1 addition & 0 deletions ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ LONGINT_IMPL = MPZ
CIRCUITPY_SPITARGET = 0
CIRCUITPY_SYNTHIO = 0
CIRCUITPY_JPEGIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
5 changes: 5 additions & 0 deletions py/circuitpy_defns.mk
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ endif
ifeq ($(CIRCUITPY_FONTIO),1)
SRC_PATTERNS += fontio/%
endif
ifeq ($(CIRCUITPY_TILEPALETTEMAPPER),1)
SRC_PATTERNS += tilepalettemapper/%
endif
ifeq ($(CIRCUITPY_TIME),1)
SRC_PATTERNS += time/%
endif
Expand Down Expand Up @@ -733,6 +736,8 @@ SRC_SHARED_MODULE_ALL = \
synthio/__init__.c \
terminalio/Terminal.c \
terminalio/__init__.c \
tilepalettemapper/__init__.c \
tilepalettemapper/TilePaletteMapper.c \
time/__init__.c \
traceback/__init__.c \
uheap/__init__.c \
Expand Down
3 changes: 3 additions & 0 deletions py/circuitpy_mpconfig.mk
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,9 @@ CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO)
CIRCUITPY_FONTIO ?= $(call enable-if-all,$(CIRCUITPY_DISPLAYIO) $(CIRCUITPY_TERMINALIO))
CFLAGS += -DCIRCUITPY_FONTIO=$(CIRCUITPY_FONTIO)

CIRCUITPY_TILEPALETTEMAPPER ?= $(CIRCUITPY_DISPLAYIO)
CFLAGS += -DCIRCUITPY_TILEPALETTEMAPPER=$(CIRCUITPY_TILEPALETTEMAPPER)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than setting two parameters in the atmel-samd/boards mpconfigboard.mk files, I think the CIRCUITPY_TERMINALIO_VT100 I recently created should default to your new parameter. (After #10108 was merged, it's being set immediately following CIRCUITPY_TERMINALIO, but doesn't show up here?). I'm also setting the VT100 parameter to 0 for all samd21 boards in the atmel-samd mpconfigport.mk which could be removed if you make this change and decide to disable the new palette for all samd21 boards 😁

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I think about it, the two features aren't technically, necessarily linked so perhaps two parameters is appropriate. Trade-offs... 🤷

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think keeping them separate makes sense, but I also don't have a strong preference one way or the other. If it's possible to set it in one spot as disabled for all SAMD21 boards that sounds more convenient than adding to each of board individually though.

Copy link

@RetiredWizard RetiredWizard Mar 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting your assignment here will turn it off for all samd21 boards by default. The board files can still turn it back on if needed.

# Turn off a few more things that don't fit in 192kB
CIRCUITPY_TERMINALIO_VT100 = 0

Edit: There were a couple of SAMD51 boards you overflowed as well though 😁 If you want to turn it off for all samd21 & samd51 boards you can use the same file and just move it outside the if block.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I do want to keep it on for any samd51s that have room. The pyportal titano for instance is what all my testing was on and it seems fine on that device.

CIRCUITPY_TIME ?= 1
CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME)

Expand Down
29 changes: 21 additions & 8 deletions shared-bindings/displayio/TileGrid.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@
#include "shared-bindings/displayio/ColorConverter.h"
#include "shared-bindings/displayio/OnDiskBitmap.h"
#include "shared-bindings/displayio/Palette.h"
#ifdef CIRCUITPY_TILEPALETTEMAPPER
#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h"
#endif


void displayio_tilegrid_validate_pixel_shader(mp_obj_t pixel_shader) {
bool valid_type = true;
if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) {
valid_type = false;
}
#if CIRCUITPY_TILEPALETTEMAPPER
if (mp_obj_is_type(pixel_shader, &tilepalettemapper_tilepalettemapper_type)) {
valid_type = true;
}
#endif
if (!valid_type) {
mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_pixel_shader);
}
}

//| class TileGrid:
//| """A grid of tiles sourced out of one bitmap
Expand Down Expand Up @@ -89,10 +108,7 @@ static mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_
mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_bitmap);
}
mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj;
if (!mp_obj_is_type(pixel_shader, &displayio_colorconverter_type) &&
!mp_obj_is_type(pixel_shader, &displayio_palette_type)) {
mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_pixel_shader);
}
displayio_tilegrid_validate_pixel_shader(pixel_shader);
uint16_t tile_width = args[ARG_tile_width].u_int;
if (tile_width == 0) {
tile_width = bitmap_width;
Expand Down Expand Up @@ -323,10 +339,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_pixel_shader_obj, displayio_til

static mp_obj_t displayio_tilegrid_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) {
displayio_tilegrid_t *self = native_tilegrid(self_in);
if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) {
mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_pixel_shader);
}

displayio_tilegrid_validate_pixel_shader(pixel_shader);
common_hal_displayio_tilegrid_set_pixel_shader(self, pixel_shader);

return mp_const_none;
Expand Down
165 changes: 165 additions & 0 deletions shared-bindings/tilepalettemapper/TilePaletteMapper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// This file is part of the CircuitPython project: https://circuitpython.org
//
// SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include <stdint.h>
#include <stdlib.h>
#include "shared/runtime/context_manager_helpers.h"
#include "py/binary.h"
#include "py/objproperty.h"
#include "py/runtime.h"
#include "shared-bindings/util.h"
#include "shared-bindings/displayio/Palette.h"
#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h"

//| class TilePaletteMapper:
//| """Contains a displayio.Palette a series of mappings from one palette color_index to another palette color_index.
//| One mapping for tile in a 2D grid. Can be set as the pixel_shader for a TileGrid to re-map the colors for
//| specific tile(s) within the TileGrid."""
//|
//| def __init__(self, palette: displayio.Palette, width: int, height: int) -> None:
//| """Create a TilePaletteMApper object to store a set of color mappings for tiles.
//|
//| :param displayio.Palette palette: The palette to get mapped colors from.
//| :param int width: The width of the grid in tiles.
//| :param int height: The height of the grid in tiles.
//| """
//| ...
//|
static mp_obj_t tilepalettemapper_tilepalettemapper_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
enum { ARG_palette, ARG_width, ARG_height };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_palette, MP_ARG_OBJ | MP_ARG_REQUIRED },
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 1} },
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 1} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mp_obj_t palette = args[ARG_palette].u_obj;
if (!mp_obj_is_type(palette, &displayio_palette_type)) {
mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_pixel_shader);
}
tilepalettemapper_tilepalettemapper_t *self = mp_obj_malloc(tilepalettemapper_tilepalettemapper_t, &tilepalettemapper_tilepalettemapper_type);
common_hal_tilepalettemapper_tilepalettemapper_construct(self, palette, args[ARG_width].u_int, args[ARG_height].u_int);

return MP_OBJ_FROM_PTR(self);
}

//| width: int
//| """Width of the tile palette mapper in tiles."""
static mp_obj_t tilepalettemapper_tilepalettemapper_obj_get_width(mp_obj_t self_in) {
tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_tilepalettemapper_tilepalettemapper_get_width(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(tilepalettemapper_tilepalettemapper_get_width_obj, tilepalettemapper_tilepalettemapper_obj_get_width);

MP_PROPERTY_GETTER(tilepalettemapper_tilepalettemapper_width_obj,
(mp_obj_t)&tilepalettemapper_tilepalettemapper_get_width_obj);

//| height: int
//| """Height of the tile palette mapper in tiles."""
static mp_obj_t tilepalettemapper_tilepalettemapper_obj_get_height(mp_obj_t self_in) {
tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_tilepalettemapper_tilepalettemapper_get_height(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(tilepalettemapper_tilepalettemapper_get_height_obj, tilepalettemapper_tilepalettemapper_obj_get_height);

MP_PROPERTY_GETTER(tilepalettemapper_tilepalettemapper_height_obj,
(mp_obj_t)&tilepalettemapper_tilepalettemapper_get_height_obj);


//| palette: displayio.Palette
//| """The palette that the mapper uses."""
//|
static mp_obj_t tilepalettemapper_tilepalettemapper_obj_get_palette(mp_obj_t self_in) {
tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_tilepalettemapper_tilepalettemapper_get_palette(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(tilepalettemapper_tilepalettemapper_get_palette_obj, tilepalettemapper_tilepalettemapper_obj_get_palette);

MP_PROPERTY_GETTER(tilepalettemapper_tilepalettemapper_palette_obj,
(mp_obj_t)&tilepalettemapper_tilepalettemapper_get_palette_obj);


//| def __getitem__(self, index: Union[Tuple[int, int], int]) -> List[int]:
//| """Returns the mapping for the given index. The index can either be an x,y tuple or an int equal
//| to ``y * width + x``.
//|
//| This allows you to::
//|
//| print(tpm[0])"""
//| ...
//|
//| def __setitem__(self, index: Union[Tuple[int, int], int], value: List[int]) -> None:
//| """Sets the mapping at the given tile index. The index can either be an x,y tuple or an int equal
//| to ``y * width + x``.
//|
//| This allows you to::
//|
//| tpm[0] = [1,0]
//|
//| or::
//|
//| tpm[0,0] = [1,0]"""
//| ...
//|
//|
static mp_obj_t tilepalettemapper_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) {
tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in);
if (mp_obj_is_type(index_obj, &mp_type_slice)) {
mp_raise_NotImplementedError(MP_ERROR_TEXT("Slices not supported"));
} else {
uint16_t x = 0;
uint16_t y = 0;
if (mp_obj_is_small_int(index_obj)) {
mp_int_t i = MP_OBJ_SMALL_INT_VALUE(index_obj);
uint16_t width = common_hal_tilepalettemapper_tilepalettemapper_get_width(self);
x = i % width;
y = i / width;
} else {
mp_obj_t *items;
mp_obj_get_array_fixed_n(index_obj, 2, &items);
x = mp_obj_get_int(items[0]);
y = mp_obj_get_int(items[1]);
}
if (x >= common_hal_tilepalettemapper_tilepalettemapper_get_width(self) ||
y >= common_hal_tilepalettemapper_tilepalettemapper_get_height(self)) {
mp_raise_IndexError(MP_ERROR_TEXT("Tile index out of bounds"));
}

if (value_obj == MP_OBJ_SENTINEL) {
// load
return common_hal_tilepalettemapper_tilepalettemapper_get_mapping(self, x, y);
} else if (value_obj == mp_const_none) {
return MP_OBJ_NULL; // op not supported
} else {
size_t len = 0;
mp_obj_t *items;
mp_obj_list_get(value_obj, &len, &items);
uint32_t palette_len = common_hal_displayio_palette_get_len(self->palette);

mp_arg_validate_int_range(len, 0, palette_len, MP_QSTR_mapping_length);
common_hal_tilepalettemapper_tilepalettemapper_set_mapping(self, x, y, len, items);
}
}
return mp_const_none;
}


static const mp_rom_map_elem_t tilepalettemapper_tilepalettemapper_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_height_obj) },
{ MP_ROM_QSTR(MP_QSTR_palette), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_palette_obj) },
};
static MP_DEFINE_CONST_DICT(tilepalettemapper_tilepalettemapper_locals_dict, tilepalettemapper_tilepalettemapper_locals_dict_table);

MP_DEFINE_CONST_OBJ_TYPE(
tilepalettemapper_tilepalettemapper_type,
MP_QSTR_TilePaletteMapper,
MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS,
make_new, tilepalettemapper_tilepalettemapper_make_new,
locals_dict, &tilepalettemapper_tilepalettemapper_locals_dict,
subscr, tilepalettemapper_subscr,
iter, mp_obj_generic_subscript_getiter
);
18 changes: 18 additions & 0 deletions shared-bindings/tilepalettemapper/TilePaletteMapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// This file is part of the CircuitPython project: https://circuitpython.org
//
// SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include "shared-module/tilepalettemapper/TilePaletteMapper.h"

extern const mp_obj_type_t tilepalettemapper_tilepalettemapper_type;

void common_hal_tilepalettemapper_tilepalettemapper_construct(tilepalettemapper_tilepalettemapper_t *self,
mp_obj_t paltte, uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles);


uint16_t common_hal_tilepalettemapper_tilepalettemapper_get_width(tilepalettemapper_tilepalettemapper_t *self);
uint16_t common_hal_tilepalettemapper_tilepalettemapper_get_height(tilepalettemapper_tilepalettemapper_t *self);
mp_obj_t common_hal_tilepalettemapper_tilepalettemapper_get_palette(tilepalettemapper_tilepalettemapper_t *self);
mp_obj_t common_hal_tilepalettemapper_tilepalettemapper_get_mapping(tilepalettemapper_tilepalettemapper_t *self, uint16_t x, uint16_t y);
void common_hal_tilepalettemapper_tilepalettemapper_set_mapping(tilepalettemapper_tilepalettemapper_t *self, uint16_t x, uint16_t y, size_t len, mp_obj_t *items);
21 changes: 21 additions & 0 deletions shared-bindings/tilepalettemapper/__init__.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// This file is part of the CircuitPython project: https://circuitpython.org
//
// SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks
//
// SPDX-License-Identifier: MIT
#include "py/obj.h"
#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h"


static const mp_rom_map_elem_t tilepalettemapper_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_tilepalettemapper) },
{ MP_ROM_QSTR(MP_QSTR_TilePaletteMapper), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_type) },
};
static MP_DEFINE_CONST_DICT(tilepalettemapper_module_globals, tilepalettemapper_module_globals_table);

const mp_obj_module_t tilepalettemapper_module = {
.base = {&mp_type_module },
.globals = (mp_obj_dict_t *)&tilepalettemapper_module_globals,
};

MP_REGISTER_MODULE(MP_QSTR_tilepalettemapper, tilepalettemapper_module);
Loading
Loading