Skip to content

Commit a37f2b3

Browse files
Update V4.3
1 parent f309a82 commit a37f2b3

File tree

10 files changed

+578
-104
lines changed

10 files changed

+578
-104
lines changed

Beta Games/BasicGame/BasicGame (Title Image).pbimg

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

Beta Games/BasicGame/BasicGame.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from PicoBoySDK import PicoBoySDK, PlayerObject
2+
3+
# Initialize the PicoBoySDK object
4+
game = PicoBoySDK("BasicGame")
5+
6+
# Load a sprite for the player
7+
player_sprite = game.Load_Sprite("/BasicGame/player.sprt", 16, 16)
8+
9+
# Initialize the player object
10+
player = PlayerObject(game, 60, 60, 16, 16, player_sprite, 2)
11+
12+
# Main game loop
13+
while True:
14+
# Fill the screen with black
15+
game.Fill_Screen((0, 0, 0))
16+
17+
# Check for player movement
18+
player.Update()
19+
20+
# Draw a boundary box
21+
game.Outline_Rect(0, 0, 120, 120, (255, 255, 255))
22+
23+
# Render a simple obstacle
24+
game.Fill_Rect(50, 50, 20, 20, (255, 0, 0))
25+
26+
# Check for collision with the obstacle
27+
collision = game.Check_Collision(
28+
player.x, player.y, player.width, player.height,
29+
50, 50, 20, 20, 0, 1
30+
)
31+
if collision:
32+
game.Create_Text("Collision!", -1, -1, (255, 255, 0))
33+
34+
# Update the game screen
35+
game.Update()

Beta Games/BasicGame/player.sprt

512 Bytes
Binary file not shown.
1.74 KB
Binary file not shown.
1.75 KB
Binary file not shown.

Libraries/Flex/Flex.py

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
# FLEXIBLE LINK EXCHANGE PROTOCOL
2+
# Designed by HalloSpaceBoy for the PicoBoy
3+
4+
"""
5+
TODO:
6+
- Modify the transfer process to use one clock signal
7+
- Add timeouts to everything
8+
- Make more detailed errors (raised at the micropy level)
9+
- Document
10+
- Test thouroughly
11+
"""
12+
"""
13+
INTRODUCTION:
14+
15+
NOTICE: This library is still in beta, use it at your own risk
16+
17+
The FLEX (Flexible Link Exchange Protocol) is a communication protocol designed for efficient, bi-directional
18+
data exchange between devices using a minimal 5-pin connection. It utilizes negotiable TX/RX roles (MX0 and MX1)
19+
and synchronized clock signals (CL0 and CL1) to facilitate reliable communication between devices, even with varying
20+
processing speeds. The protocol is interrupt-driven and asynchronous, allowing for efficient, low-latency data
21+
transfer with minimal wiring. FLEX is designed to simplify connections while ensuring stability and flexibility in
22+
communication, making it ideal for devices like the PicoBoy that require robust and scalable data exchange.
23+
24+
"""
25+
26+
"""
27+
DEVICE CONNECTION:
28+
29+
+------------------------+ +------------------------+
30+
| Device A (PicoBoy 1) | | Device B (PicoBoy 2) |
31+
|------------------------| |------------------------|
32+
| GND |-----------| GND |
33+
| MX0 |-----------| MX0 |
34+
| MX1 |-----------| MX1 |
35+
| CL0 |-----------| CL0 |
36+
| CL1 |-----------| CL1 |
37+
+------------------------+ +------------------------+
38+
39+
MX0=GPIO0
40+
MX1=GPIO1
41+
CL0=GPIO26
42+
CL1=GPIO27
43+
44+
You can use the GPIO breakout on your PicoBoy to use this.
45+
46+
47+
"""
48+
49+
50+
from machine import Pin
51+
from random import randint
52+
from time import sleep
53+
import micropython
54+
micropython.alloc_emergency_exception_buf(100)
55+
56+
57+
class Flex:
58+
def __init__(self):
59+
#user variables
60+
self.mx1=0
61+
self.mx2=1
62+
self.clk1=26
63+
self.clk2=27
64+
65+
# variable inits
66+
self.state=0
67+
self.status=False
68+
self.tx=None
69+
self.rx=None
70+
self.clkin=None
71+
self.clkout=None
72+
self.ready=False
73+
74+
#init pins
75+
Pin(self.clk1, Pin.OUT).value(0)
76+
Pin(self.clk2, Pin.OUT).value(0)
77+
Pin(self.mx1, Pin.OUT).value(0)
78+
Pin(self.mx2, Pin.OUT).value(0)
79+
80+
81+
def Port_Handshake(self):
82+
#init detect pin
83+
send_pin=Pin(self.mx2,Pin.OUT)
84+
send_pin.value(0)
85+
send_pin=Pin(self.mx2,Pin.IN,Pin.PULL_DOWN)
86+
87+
#init check pin
88+
check_pin=Pin(self.mx1, Pin.OUT)
89+
check_pin.value(0)
90+
state=0
91+
ret=False
92+
while True:
93+
#set high for random interval
94+
delay=randint(0,10)
95+
check_pin=Pin(self.mx1, Pin.OUT)
96+
check_pin.value(1)
97+
sleep(delay/1000)
98+
delay=randint(0,10)
99+
#set low and read for random interval
100+
check_pin.value(0)
101+
check_pin=Pin(self.mx1, Pin.IN ,Pin.PULL_DOWN)
102+
for i in range(delay):
103+
#if the check pin is on, handshake complete
104+
if check_pin.value()==1:
105+
send_pin=Pin(self.mx2,Pin.OUT)
106+
send_pin.value(1)
107+
ret=True
108+
while not check_pin.value()==0:
109+
sleep(0.005)
110+
pass
111+
break
112+
#if the send pin is on, other console completed handshake
113+
if send_pin.value()==1:
114+
state=1
115+
ret=True
116+
break
117+
sleep(i/1000)
118+
#break out of loop cause connected
119+
if ret:
120+
break
121+
122+
#return states and correct variables
123+
if state==0:
124+
a=(self.mx1,self.mx2)
125+
b=(self.clk1, self.clk2)
126+
else:
127+
a=(self.mx2,self.mx1)
128+
b=(self.clk2, self.clk1)
129+
return (a, state, b)
130+
131+
132+
def callback(self, v):
133+
#use this func for IRQ cause micropy does not handle interrupts well enough
134+
self.ready=True
135+
136+
def false_callback(self, v):
137+
# nothing to see here
138+
return
139+
140+
141+
142+
def Recieve(self):
143+
self.rx.irq(trigger=Pin.IRQ_FALLING, handler=self.false_callback)
144+
self.clkout.value(1) # let T know im ready
145+
while self.clkin.value()==0: #wait for first clock pulse
146+
pass
147+
self.clkout.value(0) # let T know I am synced
148+
while self.clkin.value()==1: #wait for T's CLK to be 0
149+
pass
150+
self.clkout.value(1) # let T know I am synced to clock
151+
sleep(0.005)
152+
self.clkout.value(0) # reset for communication
153+
154+
#begin recieve of amount of bytes
155+
rbyte=0b000000000000000000
156+
for i in range(16):
157+
while self.clkin.value()==0: #wait for T's CLK
158+
pass
159+
self.clkout.value(0) # let T know CLK recieved, and to wait for me
160+
z=self.rx.value()
161+
rbyte |= (z & 1) << (15 - i)
162+
self.clkout.value(1) # let T know ready for CLK low
163+
while self.clkin.value()==1: # wait for T to set CLK low
164+
pass
165+
self.clkout.value(0)
166+
167+
bytesout=[]
168+
169+
#recieve actual bytes
170+
for f in range(rbyte):
171+
nbyte=0b00000000
172+
for i in range(8):
173+
while self.clkin.value()==0: #wait for T's CLK
174+
pass
175+
self.clkout.value(0) # let T know CLK recieved, and to wait for me
176+
z=self.rx.value()
177+
nbyte |= (z & 1) << (7 - i)
178+
self.clkout.value(1) # let T know ready for CLK low
179+
while self.clkin.value()==1: # wait for T to set CLK low
180+
pass
181+
#send ready signal
182+
self.clkout.value(0)
183+
#append recieved byte to list
184+
bytesout.append(nbyte)
185+
186+
#Reset values
187+
self.clkout.value(0)
188+
self.tx.value(1)
189+
self.ready=False
190+
self.rx.irq(trigger=Pin.IRQ_FALLING, handler=self.callback)
191+
o=bytes(bytesout)
192+
try:
193+
if o.decode()=="£¾ãØãä4|":
194+
self.Disconnect(False)
195+
return
196+
except:
197+
"Could not decode to string"
198+
return bytes(bytesout)
199+
200+
201+
202+
203+
def Send(self, byts):
204+
#get amount of bytes
205+
amount = len(byts)
206+
207+
#Handshake
208+
self.tx.value(0) #send interrupt to r
209+
while self.clkin.value()==0: # wait for r
210+
pass
211+
self.clkout.value(1) # tell R to sync
212+
while self.clkin.value()==1: # wait for r to confirm sync
213+
pass
214+
self.clkout.value(0) #initialize clock
215+
while self.clkin.value()==0: # wait for r to confirm clock sync
216+
pass
217+
218+
219+
#send number of bytes
220+
for i in range(15, -1, -1):
221+
bit = (amount >> i) & 1 # get bit to send
222+
self.clkout.value(1) # tell R to enter read mode read
223+
self.tx.value(bit) # send data to R
224+
while self.clkin.value()==1:# wait for R to confirm entrance
225+
pass
226+
while self.clkin.value()==0: # wait for confirmation of recipt
227+
pass
228+
self.clkout.value(0) # tell R to stop reading
229+
while self.clkin.value()==1: # wait for R to confirm ready for next pulse
230+
pass
231+
232+
#send each byte
233+
for byte in byts:
234+
for i in range(7, -1, -1):
235+
bit = (byte >> i) & 1 # get bit to send
236+
self.clkout.value(1) # tell R to enter read mode read
237+
self.tx.value(bit) # send data to R
238+
while self.clkin.value()==1:# wait for R to confirm entrance
239+
pass
240+
while self.clkin.value()==0: # wait for confirmation of recipt
241+
pass
242+
self.clkout.value(0) # tell R to stop reading
243+
while self.clkin.value()==1: # wait for R to confirm ready for next pulse
244+
pass
245+
246+
247+
#Reset pins
248+
self.tx.value(1)
249+
self.clkout.value(0)
250+
251+
def Check_Read(self):
252+
# check for a read by polling even though there is an irq
253+
if self.ready==True:
254+
return self.Recieve()
255+
256+
257+
def Connect(self):
258+
Pins=self.Port_Handshake()
259+
self.state=Pins[1]
260+
self.clkout=Pin(Pins[2][0], Pin.OUT)
261+
self.clkin=Pin(Pins[2][1], Pin.IN, Pin.PULL_DOWN)
262+
self.tx=Pin(Pins[0][0], Pin.OUT)
263+
self.tx.value(1)
264+
self.rx=Pin(Pins[0][1], Pin.IN, Pin.PULL_DOWN)
265+
self.rx.irq(trigger=Pin.IRQ_FALLING, handler=self.callback)
266+
267+
def Disconnect(self, d=True):
268+
if d:
269+
# using random string that is very uncommon for sending disconnect signal
270+
# 1 in ~3 quintillion chance of accidentally sending
271+
self.Send('£¾ãØãä4|'.encode())
272+
self.rx.irq(trigger=Pin.IRQ_FALLING, handler=self.false_callback)
273+
self.state=0
274+
self.tx=None
275+
self.rx=None
276+
self.clkin=None
277+
self.clkout=None
278+
self.ready=False
279+
Pin(self.clk1, Pin.OUT).value(0)
280+
Pin(self.clk2, Pin.OUT).value(0)
281+
Pin(self.mx1, Pin.OUT).value(0)
282+
Pin(self.mx2, Pin.OUT).value(0)
283+
284+
285+
286+
287+
288+
289+
290+
# Demo use: Sending text from one picoboy to another (Using the Thonny shell)
291+
# uncomment to run as a file
292+
"""
293+
comm=Flex()
294+
input("Press enter to connect...")
295+
comm.Connect()
296+
from PicoGameBoy import PicoGameBoy
297+
from sys import exit
298+
pgb=PicoGameBoy()
299+
300+
301+
if comm.state==0:
302+
while True:
303+
l=input("Send: ")
304+
if l=="disconnect":
305+
comm.Disconnect()
306+
exit()
307+
l=l.encode()
308+
comm.Send(l)
309+
else:
310+
while True:
311+
l=comm.Check_Read()
312+
if not l==None:
313+
last=l
314+
print(last.decode())
315+
pgb.fill(PicoGameBoy.color(0,0,0))
316+
pgb.create_text(last.decode(),-1,-1,PicoGameBoy.color(255,255,255))
317+
pgb.show_screen()
318+
"""
319+
320+
321+
322+
323+
324+
325+

0 commit comments

Comments
 (0)