-
Notifications
You must be signed in to change notification settings - Fork 2
/
emulator.py
executable file
·120 lines (103 loc) · 3.81 KB
/
emulator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
pymlgame - Mate Light emulator
==============================
This little program emulates the awesome Mate Light, just in case you're not on c-base space station but want to send
something to it.
Usage:
emulator.py [-w=<px>] [-h=<px>] [--host=<ip>] [--port=<num>] [--dot=<size>]
emulator.py --help
emulator.py --version
Options:
--help Show this screen.
--version Show version.
-w=<px> Width in pixels [default: 40].
-h=<px> Height in pixels [default: 16].
--host=<host> Bind to IP address [default: 127.0.0.1].
--port=<port> Bind to Port [default: 1337].
--dot=<px> Size of dots in pixels [default: 10].
"""
__author__ = 'Ricardo Band'
__copyright__ = 'Ricardo Band'
__credits__ = ['Ricardo Band']
__license__ = 'MIT'
__version__ = '0.3.1'
__maintainer__ = 'Ricardo Band'
__email__ = '[email protected]'
__status__ = 'Development'
import sys
import socket
import pygame
from docopt import docopt
class Emu(object):
"""
The Emulator is a simple pygame game.
"""
def __init__(self, width=40, height=16, ip='127.0.0.1', port=1337, dotsize=10):
"""
Creates a screen with the given size, generates the matrix for the Mate bottles and binds the socket for
incoming frames.
"""
self.width = width
self.height = height
self.dotsize = dotsize
pygame.init()
self.screen = pygame.display.set_mode([self.width * self.dotsize, self.height * self.dotsize])
pygame.display.set_caption("Mate Light Emu")
self.clock = pygame.time.Clock()
self.matrix = []
for c in range(self.width * self.height * 3):
self.matrix.append(0)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.bind((ip, port))
# size is width * height * 3 (rgb) + 4 (checksum)
self.packetsize = self.width * self.height * 3 + 4
def recv_data(self):
"""
Grab the next frame and put it on the matrix.
"""
data, addr = self.sock.recvfrom(self.packetsize)
matrix = map(ord, data.strip())
if len(matrix) == self.packetsize:
self.matrix = matrix[:-4]
def update(self):
"""
Generate the output from the matrix.
"""
pixels = len(self.matrix)
for x in range(self.width):
for y in range(self.height):
pixel = y * self.width * 3 + x * 3
#TODO: sometimes the matrix is not as big as it should
if pixel < pixels:
pygame.draw.circle(self.screen,
(self.matrix[pixel], self.matrix[pixel + 1], self.matrix[pixel + 2]),
(x * self.dotsize + self.dotsize / 2, y * self.dotsize + self.dotsize / 2), self.dotsize / 2, 0)
def render(self):
"""
Output the current screen.
"""
pygame.display.update()
pygame.display.flip()
def gameloop(self):
"""
Loop through all the necessary stuff and end execution when Ctrl+C was hit.
"""
try:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.event.post(pygame.event.Event(pygame.QUIT))
self.recv_data()
self.update()
self.render()
except KeyboardInterrupt:
pass
if __name__ == '__main__':
ARGS = docopt(__doc__, version=__version__)
EMU = Emu(int(ARGS['-w']), int(ARGS['-h']), ARGS['--host'], int(ARGS['--port']), int(ARGS['--dot']))
EMU.gameloop()