|
| 1 | +from micropython import const |
| 2 | +import board |
| 3 | +import busio |
| 4 | +import digitalio |
| 5 | +import time |
| 6 | +import ugame |
| 7 | +import stage |
| 8 | +import array |
| 9 | + |
| 10 | + |
| 11 | +_FONT = ( |
| 12 | + b'{{{{{{wws{w{HY{{{{YDYDY{sUtGUsH[wyH{uHgHE{ws{{{{vyxyv{g[K[g{{]f]{{{wDw{{' |
| 13 | + b'{{{wy{{{D{{{{{{{w{K_w}x{VHLHe{wuwww{`KfyD{UKgKU{w}XDK{DxTKT{VxUHU{D[wyx{' |
| 14 | + b'UHfHU{UHEKe{{w{w{{{w{wy{KwxwK{{D{D{{xwKwx{eKg{w{VIHyB{fYH@H{dHdHd{FyxyF{' |
| 15 | + b'`XHX`{DxtxD{Dxtxx{FyxIF{HHDHH{wwwww{KKKHU{HXpXH{xxxxD{Y@DLH{IL@LX{fYHYf{' |
| 16 | + b'`HH`x{fYHIF{`HH`H{UxUKU{Dwwww{HHHIR{HHH]w{HHLD@{HYsYH{HYbww{D[wyD{txxxt{' |
| 17 | + b'x}w_K{GKKKG{wLY{{{{{{{{Dxs{{{{{BIIB{x`XX`{{ByyB{KBIIB{{WIpF{OwUwww{`YB[`' |
| 18 | + b'x`XHH{w{vwc{K{OKHUxHpXH{vwws_{{dD@H{{`XHH{{fYYf{{`XX`x{bYIBK{Ipxx{{F}_d{' |
| 19 | + b'wUws_{{HHIV{{HH]s{{HLD@{{HbbH{{HHV[a{D_}D{Cw|wC{wwwwwwpwOwp{WKfxu{@YYY@{' |
| 20 | +) |
| 21 | +_SALT = const(132) |
| 22 | + |
| 23 | +_PALETTE = array.array('H', (0x0, 0x4a29, 0x6004, 0xf8, 0xfd, 0xf42, 0x825b, |
| 24 | + 0xf8, 0xfe, 0x125b, 0xcffb, 0xe0cf, 0xffff, |
| 25 | + 0x1ff8, 0xdbff, 0xffff)) |
| 26 | + |
| 27 | +K_X = ugame.K_X |
| 28 | +K_DOWN = ugame.K_DOWN |
| 29 | +K_LEFT = ugame.K_LEFT |
| 30 | +K_RIGHT = ugame.K_RIGHT |
| 31 | +K_UP = ugame.K_UP |
| 32 | +K_O = ugame.K_O |
| 33 | + |
| 34 | +_tick = None |
| 35 | +_display = None |
| 36 | + |
| 37 | + |
| 38 | +def brightness(level): |
| 39 | + pass |
| 40 | + |
| 41 | + |
| 42 | +def show(pix): |
| 43 | + for y in range(8): |
| 44 | + for x in range(8): |
| 45 | + _grid.tile(x + 1, y, 1 + (pix.pixel(x, y) & 0x03)) |
| 46 | + _game.render_block(16, 0, 144, 128) |
| 47 | + |
| 48 | +keys = ugame.buttons.get_pressed |
| 49 | + |
| 50 | + |
| 51 | +def tick(delay): |
| 52 | + global _tick |
| 53 | + |
| 54 | + now = time.monotonic() |
| 55 | + _tick += delay |
| 56 | + if _tick < now: |
| 57 | + _tick = now |
| 58 | + else: |
| 59 | + time.sleep(_tick - now) |
| 60 | + |
| 61 | + |
| 62 | +class GameOver(SystemExit): |
| 63 | + pass |
| 64 | + |
| 65 | + |
| 66 | +class Pix: |
| 67 | + __slots__ = ('buffer', 'width', 'height') |
| 68 | + |
| 69 | + def __init__(self, width=8, height=8, buffer=None): |
| 70 | + if buffer is None: |
| 71 | + buffer = bytearray(width * height) |
| 72 | + self.buffer = buffer |
| 73 | + self.width = width |
| 74 | + self.height = height |
| 75 | + |
| 76 | + @classmethod |
| 77 | + def from_text(cls, string, color=None, bgcolor=0, colors=None): |
| 78 | + pix = cls(4 * len(string), 6) |
| 79 | + font = memoryview(_FONT) |
| 80 | + if colors is None: |
| 81 | + if color is None: |
| 82 | + colors = (3, 2, bgcolor, bgcolor) |
| 83 | + else: |
| 84 | + colors = (color, color, bgcolor, bgcolor) |
| 85 | + x = 0 |
| 86 | + for c in string: |
| 87 | + index = ord(c) - 0x20 |
| 88 | + if not 0 <= index <= 95: |
| 89 | + continue |
| 90 | + row = 0 |
| 91 | + for byte in font[index * 6:index * 6 + 6]: |
| 92 | + unsalted = byte ^ _SALT |
| 93 | + for col in range(4): |
| 94 | + pix.pixel(x + col, row, colors[unsalted & 0x03]) |
| 95 | + unsalted >>= 2 |
| 96 | + row += 1 |
| 97 | + x += 4 |
| 98 | + return pix |
| 99 | + |
| 100 | + @classmethod |
| 101 | + def from_iter(cls, lines): |
| 102 | + pix = cls(len(lines[0]), len(lines)) |
| 103 | + y = 0 |
| 104 | + for line in lines: |
| 105 | + x = 0 |
| 106 | + for pixel in line: |
| 107 | + pix.pixel(x, y, pixel) |
| 108 | + x += 1 |
| 109 | + y += 1 |
| 110 | + return pix |
| 111 | + |
| 112 | + def pixel(self, x, y, color=None): |
| 113 | + if not 0 <= x < self.width or not 0 <= y < self.height: |
| 114 | + return 0 |
| 115 | + if color is None: |
| 116 | + return self.buffer[x + y * self.width] |
| 117 | + self.buffer[x + y * self.width] = color |
| 118 | + |
| 119 | + def box(self, color, x=0, y=0, width=None, height=None): |
| 120 | + x = min(max(x, 0), self.width - 1) |
| 121 | + y = min(max(y, 0), self.height - 1) |
| 122 | + width = max(0, min(width or self.width, self.width - x)) |
| 123 | + height = max(0, min(height or self.height, self.height - y)) |
| 124 | + for y in range(y, y + height): |
| 125 | + xx = y * self.width + x |
| 126 | + for i in range(width): |
| 127 | + self.buffer[xx] = color |
| 128 | + xx += 1 |
| 129 | + |
| 130 | + def blit(self, source, dx=0, dy=0, x=0, y=0, |
| 131 | + width=None, height=None, key=None): |
| 132 | + if dx < 0: |
| 133 | + x -= dx |
| 134 | + dx = 0 |
| 135 | + if x < 0: |
| 136 | + dx -= x |
| 137 | + x = 0 |
| 138 | + if dy < 0: |
| 139 | + y -= dy |
| 140 | + dy = 0 |
| 141 | + if y < 0: |
| 142 | + dy -= y |
| 143 | + y = 0 |
| 144 | + width = min(min(width or source.width, source.width - x), |
| 145 | + self.width - dx) |
| 146 | + height = min(min(height or source.height, source.height - y), |
| 147 | + self.height - dy) |
| 148 | + source_buffer = memoryview(source.buffer) |
| 149 | + self_buffer = self.buffer |
| 150 | + if key is None: |
| 151 | + for row in range(height): |
| 152 | + xx = y * source.width + x |
| 153 | + dxx = dy * self.width + dx |
| 154 | + self_buffer[dxx:dxx + width] = source_buffer[xx:xx + width] |
| 155 | + y += 1 |
| 156 | + dy += 1 |
| 157 | + else: |
| 158 | + for row in range(height): |
| 159 | + xx = y * source.width + x |
| 160 | + dxx = dy * self.width + dx |
| 161 | + for col in range(width): |
| 162 | + color = source_buffer[xx] |
| 163 | + if color != key: |
| 164 | + self_buffer[dxx] = color |
| 165 | + dxx += 1 |
| 166 | + xx += 1 |
| 167 | + y += 1 |
| 168 | + dy += 1 |
| 169 | + |
| 170 | + def __str__(self): |
| 171 | + return "\n".join( |
| 172 | + "".join( |
| 173 | + ('.', '+', '*', '@')[self.pixel(x, y)] |
| 174 | + for x in range(self.width) |
| 175 | + ) |
| 176 | + for y in range(self.height) |
| 177 | + ) |
| 178 | + |
| 179 | + |
| 180 | +def init(): |
| 181 | + global _tick, _display, _bitmap, _grid, _game |
| 182 | + |
| 183 | + if _tick is not None: |
| 184 | + return |
| 185 | + |
| 186 | + _tick = time.monotonic() |
| 187 | + |
| 188 | + _game = stage.Stage(ugame.display, 12) |
| 189 | + _bank = bytearray(2048) |
| 190 | + for c in range(16): |
| 191 | + for y in range(0, 15): |
| 192 | + for x in range(0, 7): |
| 193 | + _bank[c * 128 + y * 8 + x] = c | c << 4 |
| 194 | + _bank[c * 128 + y * 8 + 7] = c << 4 |
| 195 | + _bank[c * 128] = c |
| 196 | + _bank[c * 128 + 7] = 0 |
| 197 | + _bank[c * 128 + 14 * 8] = c |
| 198 | + _bank[c * 128 + 14 * 8 + 7] = 0 |
| 199 | + tiles = stage.Bank(_bank, _PALETTE) |
| 200 | + _grid = stage.Grid(tiles, 10, 8) |
| 201 | + _grid.move(0, 0) |
| 202 | + _game.layers = [_grid] |
| 203 | + _game.render_block() |
0 commit comments