Skip to content

Commit 3020d92

Browse files
committed
Add support for PewPew Pi
1 parent 9a8338b commit 3020d92

File tree

5 files changed

+286
-203
lines changed

5 files changed

+286
-203
lines changed

pew.py

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
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

Comments
 (0)