Skip to content

Commit 2975057

Browse files
committed
add support for inverted tiles in TileGrid
1 parent 000600a commit 2975057

File tree

7 files changed

+98
-0
lines changed

7 files changed

+98
-0
lines changed

shared-bindings/displayio/TileGrid.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,42 @@ MP_PROPERTY_GETSET(displayio_tilegrid_bitmap_obj,
385385
(mp_obj_t)&displayio_tilegrid_get_bitmap_obj,
386386
(mp_obj_t)&displayio_tilegrid_set_bitmap_obj);
387387

388+
//| def get_inverted(self, tile_coords: tuple) -> bool:
389+
//| """Returns True if the tile at the given x, y coordinates is inverted."""
390+
//|
391+
static mp_obj_t displayio_tilegrid_obj_get_inverted(mp_obj_t self_in, mp_obj_t tile_coords) {
392+
displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in);
393+
394+
mp_obj_t *tile_coords_items;
395+
mp_obj_get_array_fixed_n(tile_coords, 2, &tile_coords_items);
396+
uint16_t x = 0;
397+
uint16_t y = 0;
398+
x = mp_obj_get_int(tile_coords_items[0]);
399+
y = mp_obj_get_int(tile_coords_items[1]);
400+
401+
return mp_obj_new_bool(common_hal_displayio_tilegrid_get_inverted(self, x, y));
402+
}
403+
MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_get_inverted_obj, displayio_tilegrid_obj_get_inverted);
404+
405+
//| def set_inverted(self, tile_coords: tuple, inverted: bool) -> None:
406+
//| """Set the tile at the given x, y coordinates to be inverted or not."""
407+
//|
408+
static mp_obj_t displayio_tilegrid_obj_set_inverted(mp_obj_t self_in, mp_obj_t tile_coords, mp_obj_t inverted_obj) {
409+
displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in);
410+
411+
mp_obj_t *tile_coords_items;
412+
mp_obj_get_array_fixed_n(tile_coords, 2, &tile_coords_items);
413+
uint16_t x = 0;
414+
uint16_t y = 0;
415+
x = mp_obj_get_int(tile_coords_items[0]);
416+
y = mp_obj_get_int(tile_coords_items[1]);
417+
bool inverted = mp_obj_is_true(inverted_obj);
418+
419+
common_hal_displayio_tilegrid_set_inverted(self, x, y, inverted);
420+
return mp_const_none;
421+
}
422+
MP_DEFINE_CONST_FUN_OBJ_3(displayio_tilegrid_set_inverted_obj, displayio_tilegrid_obj_set_inverted);
423+
388424
//| def __getitem__(self, index: Union[Tuple[int, int], int]) -> int:
389425
//| """Returns the tile index at the given index. The index can either be an x,y tuple or an int equal
390426
//| to ``y * width + x``.
@@ -461,6 +497,8 @@ static const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table[] = {
461497
{ MP_ROM_QSTR(MP_QSTR_flip_y), MP_ROM_PTR(&displayio_tilegrid_flip_y_obj) },
462498
{ MP_ROM_QSTR(MP_QSTR_transpose_xy), MP_ROM_PTR(&displayio_tilegrid_transpose_xy_obj) },
463499
{ MP_ROM_QSTR(MP_QSTR_contains), MP_ROM_PTR(&displayio_tilegrid_contains_obj) },
500+
{ MP_ROM_QSTR(MP_QSTR_get_inverted), MP_ROM_PTR(&displayio_tilegrid_get_inverted_obj) },
501+
{ MP_ROM_QSTR(MP_QSTR_set_inverted), MP_ROM_PTR(&displayio_tilegrid_set_inverted_obj) },
464502
{ MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&displayio_tilegrid_pixel_shader_obj) },
465503
{ MP_ROM_QSTR(MP_QSTR_bitmap), MP_ROM_PTR(&displayio_tilegrid_bitmap_obj) },
466504
};

shared-bindings/displayio/TileGrid.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ uint16_t common_hal_displayio_tilegrid_get_tile_height(displayio_tilegrid_t *sel
4646
uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
4747
void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index);
4848

49+
bool common_hal_displayio_tilegrid_get_inverted(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
50+
void common_hal_displayio_tilegrid_set_inverted(displayio_tilegrid_t *self, uint16_t x, uint16_t y, bool inverted);
51+
4952
// Private API for scrolling the TileGrid.
5053
void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
5154
void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint8_t tile_index);

shared-module/displayio/TileGrid.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_
1717
mp_obj_t pixel_shader, uint16_t width, uint16_t height,
1818
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile) {
1919
uint32_t total_tiles = width * height;
20+
self->inverts = (bool *)m_malloc(total_tiles);
2021
// Sprites will only have one tile so save a little memory by inlining values in the pointer.
2122
uint8_t inline_tiles = sizeof(uint8_t *);
2223
if (total_tiles <= inline_tiles) {
@@ -54,6 +55,7 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_
5455
self->flip_y = false;
5556
self->transpose_xy = false;
5657
self->absolute_transform = NULL;
58+
displayio_tilegird_clear_inverts(self);
5759
}
5860

5961

@@ -65,6 +67,14 @@ bool displayio_tilegrid_get_rendered_hidden(displayio_tilegrid_t *self) {
6567
return self->rendered_hidden;
6668
}
6769

70+
void displayio_tilegird_clear_inverts(displayio_tilegrid_t *self) {
71+
for (uint16_t x = 0; x < self->width_in_tiles; x++) {
72+
for (uint16_t y = 0; y < self->height_in_tiles; y++) {
73+
self->inverts[y * self->width_in_tiles + x] = false;
74+
}
75+
}
76+
}
77+
6878
void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t *self, bool hidden) {
6979
self->hidden = hidden;
7080
self->rendered_hidden = false;
@@ -355,6 +365,16 @@ bool common_hal_displayio_tilegrid_contains(displayio_tilegrid_t *self, uint16_t
355365
y >= self->y && y < bottom_edge;
356366
}
357367

368+
bool common_hal_displayio_tilegrid_get_inverted(displayio_tilegrid_t *self, uint16_t x, uint16_t y) {
369+
uint16_t tile_location = y * self->width_in_tiles + x;
370+
return self->inverts[tile_location];
371+
}
372+
373+
void common_hal_displayio_tilegrid_set_inverted(displayio_tilegrid_t *self, uint16_t x, uint16_t y, bool inverted) {
374+
uint16_t tile_location = y * self->width_in_tiles + x;
375+
self->inverts[tile_location] = inverted;
376+
}
377+
358378
void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y) {
359379
self->top_left_x = x;
360380
self->top_left_y = y;
@@ -484,6 +504,16 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self,
484504
input_pixel.pixel = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, input_pixel.tile_x, input_pixel.tile_y);
485505
}
486506

507+
if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type) && common_hal_displayio_palette_get_len(self->pixel_shader) == 2) {
508+
if (self->inverts[tile_location]) {
509+
if (input_pixel.pixel == 0) {
510+
input_pixel.pixel = 1;
511+
}else if (input_pixel.pixel == 1) {
512+
input_pixel.pixel = 0;
513+
}
514+
}
515+
}
516+
487517
output_pixel.opaque = true;
488518
if (self->pixel_shader == mp_const_none) {
489519
output_pixel.pixel = input_pixel.pixel;

shared-module/displayio/TileGrid.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ typedef struct {
3131
uint16_t top_left_x;
3232
uint16_t top_left_y;
3333
uint8_t *tiles;
34+
bool *inverts;
3435
const displayio_buffer_transform_t *absolute_transform;
3536
displayio_area_t dirty_area; // Stored as a relative area until the refresh area is fetched.
3637
displayio_area_t previous_area; // Stored as an absolute area.
@@ -67,3 +68,5 @@ bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_
6768
void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self);
6869

6970
bool displayio_tilegrid_get_rendered_hidden(displayio_tilegrid_t *self);
71+
72+
void displayio_tilegird_clear_inverts(displayio_tilegrid_t *self);

shared-module/terminalio/Terminal.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "shared-module/fontio/BuiltinFont.h"
1010
#include "shared-bindings/displayio/TileGrid.h"
11+
#include "shared-module/displayio/TileGrid.h"
1112
#include "shared-bindings/terminalio/Terminal.h"
1213

1314
#if CIRCUITPY_STATUS_BAR
@@ -33,8 +34,10 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
3334
self->status_y = 0;
3435
self->first_row = 0;
3536
common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0);
37+
displayio_tilegird_clear_inverts(scroll_area);
3638
if (self->status_bar) {
3739
common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0);
40+
displayio_tilegird_clear_inverts(self->status_bar);
3841
}
3942

4043
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 1);

supervisor/shared/display.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extern displayio_group_t circuitpython_splash;
4646

4747
#if CIRCUITPY_TERMINALIO
4848
static uint8_t *tilegrid_tiles = NULL;
49+
static bool *tilegrid_inverts = NULL;
4950
static size_t tilegrid_tiles_size = 0;
5051
#endif
5152

@@ -93,6 +94,21 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
9394
return;
9495
}
9596
}
97+
if (tilegrid_inverts) {
98+
if (tilegrid_tiles_size != total_tiles) {
99+
port_free(tilegrid_inverts);
100+
tilegrid_inverts = NULL;
101+
tilegrid_tiles_size = 0;
102+
reset_tiles = true;
103+
}
104+
}
105+
if (!tilegrid_inverts) {
106+
tilegrid_inverts = port_malloc(total_tiles, false);
107+
reset_tiles = true;
108+
if (!tilegrid_inverts) {
109+
return;
110+
}
111+
}
96112

97113
if (reset_tiles) {
98114
// Adjust the display dimensions to account for scale of the outer group.
@@ -117,6 +133,7 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
117133
status_bar->x = width_px - status_bar->pixel_width;
118134
status_bar->top_left_y = 0;
119135
status_bar->tiles = tilegrid_tiles;
136+
status_bar->inverts = tilegrid_inverts;
120137
status_bar->full_change = true;
121138

122139
scroll_area->width_in_tiles = width_in_tiles;
@@ -131,6 +148,7 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
131148
// may be clipped by the status bar and that's ok.
132149
scroll_area->y = height_px - scroll_area->pixel_height;
133150
scroll_area->tiles = tilegrid_tiles + width_in_tiles;
151+
scroll_area->inverts = tilegrid_inverts + width_in_tiles;
134152
scroll_area->full_change = true;
135153

136154
common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, status_bar);

tools/gen_display_resources.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ def _load_row(self, y, row):
225225
.top_left_x = {0},
226226
.top_left_y = {0},
227227
.tiles = 0,
228+
.inverts = false,
228229
.partial_change = false,
229230
.full_change = false,
230231
.hidden = false,
@@ -275,6 +276,7 @@ def _load_row(self, y, row):
275276
.tile_width = {1},
276277
.tile_height = {2},
277278
.tiles = NULL,
279+
.inverts = NULL,
278280
.partial_change = false,
279281
.full_change = false,
280282
.hidden = false,
@@ -303,6 +305,7 @@ def _load_row(self, y, row):
303305
.tile_width = {1},
304306
.tile_height = {2},
305307
.tiles = NULL,
308+
.inverts = NULL,
306309
.partial_change = false,
307310
.full_change = false,
308311
.hidden = false,

0 commit comments

Comments
 (0)