Finished full client to web stack, works fine
parent
e760498b3b
commit
581bcd71e9
|
@ -12,7 +12,7 @@ local_port = 5001
|
||||||
# UDP webserver port to bypass frameserver for testing
|
# UDP webserver port to bypass frameserver for testing
|
||||||
remote_port = 4422
|
remote_port = 4422
|
||||||
# port to frameserver
|
# port to frameserver
|
||||||
#remote_port = 4321
|
remote_port = 4321
|
||||||
|
|
||||||
# TODO: autodetect interface address for remote application
|
# TODO: autodetect interface address for remote application
|
||||||
outgoing_if = "127.0.0.1"
|
outgoing_if = "127.0.0.1"
|
||||||
|
@ -56,6 +56,9 @@ frequency = 1000 / sleeptime # frames per second
|
||||||
|
|
||||||
# function resets map to zero
|
# function resets map to zero
|
||||||
def set_wdata(r, g, b):
|
def set_wdata(r, g, b):
|
||||||
|
global wdata
|
||||||
|
wdata = []
|
||||||
|
|
||||||
for x in xrange(width):
|
for x in xrange(width):
|
||||||
wdata.append([0] * height)
|
wdata.append([0] * height)
|
||||||
for y in xrange(height):
|
for y in xrange(height):
|
||||||
|
@ -80,6 +83,21 @@ def i2c(rgba):
|
||||||
# ignore rgba[0] because it is the state
|
# ignore rgba[0] because it is the state
|
||||||
return chr(int(rgba[1])) + chr(int(rgba[2])) + chr(int(rgba[3])) + chr(int(rgba[4]))
|
return chr(int(rgba[1])) + chr(int(rgba[2])) + chr(int(rgba[3])) + chr(int(rgba[4]))
|
||||||
|
|
||||||
|
# determine if a cells neighbour is active (any will do)
|
||||||
|
def has_active_neighb(x, y):
|
||||||
|
# check the cell to the left
|
||||||
|
if x > 0 and wdata[x - 1][y][0] > 0:
|
||||||
|
return True
|
||||||
|
# check the cell above
|
||||||
|
if y > 0 and wdata[x][y - 1][0] > 0:
|
||||||
|
return True
|
||||||
|
# check the cell to the right
|
||||||
|
if x < (width - 1) and wdata[x + 1][y][0] > 0:
|
||||||
|
return True
|
||||||
|
# check the cell below
|
||||||
|
if y < (height - 1) and wdata[x][y + 1][0] > 0:
|
||||||
|
return True
|
||||||
|
|
||||||
# function sends wdata and sdata state to server
|
# function sends wdata and sdata state to server
|
||||||
def send_update():
|
def send_update():
|
||||||
#zero out the data buffer
|
#zero out the data buffer
|
||||||
|
@ -105,33 +123,21 @@ def send_update():
|
||||||
# send the data packet to remote host
|
# send the data packet to remote host
|
||||||
UDPSock.sendto(data,(remote_host,remote_port))
|
UDPSock.sendto(data,(remote_host,remote_port))
|
||||||
|
|
||||||
# initialize map
|
# main loop
|
||||||
|
while True:
|
||||||
|
# reset/initialize map
|
||||||
set_wdata(67,67,67)
|
set_wdata(67,67,67)
|
||||||
set_sdata(0,0,255)
|
set_sdata(255,255,255)
|
||||||
|
|
||||||
# set start seed
|
# set start seed
|
||||||
# get random location
|
# get random location
|
||||||
rx = randint(0, width - 1)
|
rx = randint(0, width - 1)
|
||||||
ry = randint(0, height - 1)
|
ry = randint(0, height - 1)
|
||||||
wdata[rx][ry] = [1,1,0,0,1]
|
wdata[rx][ry] = [1,1,0,0,1]
|
||||||
print "origin(" + str(rx) + "," + str(ry) + ")"
|
# print "origin(" + str(rx) + "," + str(ry) + ")"
|
||||||
|
|
||||||
def has_active_neighb(x, y):
|
|
||||||
# check the cell to the left
|
|
||||||
if x > 0 and wdata[x - 1][y][0] > 0:
|
|
||||||
return True
|
|
||||||
# check the cell above
|
|
||||||
if y > 0 and wdata[x][y - 1][0] > 0:
|
|
||||||
return True
|
|
||||||
# check the cell to the right
|
|
||||||
if x < (width - 1) and wdata[x + 1][y][0] > 0:
|
|
||||||
return True
|
|
||||||
# check the cell below
|
|
||||||
if y < (height - 1) and wdata[x][y + 1][0] > 0:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# main logic loop
|
# main logic loop
|
||||||
for t in range(60):
|
for t in range(23):
|
||||||
|
|
||||||
# push update to clients
|
# push update to clients
|
||||||
send_update()
|
send_update()
|
||||||
|
@ -144,47 +150,29 @@ for t in range(60):
|
||||||
# if cell is active, increase its rating/value
|
# if cell is active, increase its rating/value
|
||||||
if wdata[x][y][0] > 0:
|
if wdata[x][y][0] > 0:
|
||||||
# change the state of the cell
|
# change the state of the cell
|
||||||
data_buffer[x][y][0] += 10
|
data_buffer[x][y][0] += 16
|
||||||
|
|
||||||
# assign stat to red colour
|
# assign stat to red colour
|
||||||
data_buffer[x][y][1] = data_buffer[x][y][0]
|
data_buffer[x][y][1] = data_buffer[x][y][0]
|
||||||
|
|
||||||
# check we don't go too high
|
# check we don't go too high
|
||||||
|
# if the state is over 127, reset red
|
||||||
if data_buffer[x][y][0] > 127:
|
if data_buffer[x][y][0] > 127:
|
||||||
data_buffer[x][y][1] = 127
|
# assign max stat to red colour
|
||||||
|
data_buffer[x][y][1] = 0
|
||||||
# assign stat to green colour
|
# assign stat to green colour
|
||||||
data_buffer[x][y][2] = data_buffer[x][y][0] - 127
|
data_buffer[x][y][2] = data_buffer[x][y][0] - 128
|
||||||
|
|
||||||
|
# if the state is over 128*2, reset green
|
||||||
if data_buffer[x][y][0] > 255:
|
if data_buffer[x][y][0] > 255:
|
||||||
data_buffer[x][y][2] = 127
|
# assign max stat to green colour
|
||||||
|
data_buffer[x][y][2] = 0
|
||||||
# assign stat to blue colour
|
# assign stat to blue colour
|
||||||
data_buffer[x][y][3] = data_buffer[x][y][0] - 255
|
data_buffer[x][y][3] = data_buffer[x][y][0] - 255
|
||||||
|
|
||||||
|
# if the state is over 128*3, reset blue
|
||||||
if data_buffer[x][y][0] > 383:
|
if data_buffer[x][y][0] > 383:
|
||||||
data_buffer[x][y][3] = 127
|
data_buffer[x][y][3] = data_buffer[x][y][0]%128
|
||||||
|
|
||||||
set_sdata(0,0,0)
|
|
||||||
# E
|
|
||||||
sdata[0][0] = [0,255,0,0,1]
|
|
||||||
sdata[0][3] = [0,255,0,0,1]
|
|
||||||
sdata[0][4] = [0,255,0,0,1]
|
|
||||||
sdata[0][5] = [0,255,0,0,1]
|
|
||||||
sdata[0][6] = [0,255,0,0,1]
|
|
||||||
# N
|
|
||||||
sdata[1][2] = [0,255,0,0,1]
|
|
||||||
sdata[1][4] = [0,255,0,0,1]
|
|
||||||
sdata[1][5] = [0,255,0,0,1]
|
|
||||||
sdata[1][6] = [0,255,0,0,1]
|
|
||||||
# D
|
|
||||||
sdata[2][1] = [0,255,0,0,1]
|
|
||||||
sdata[2][2] = [0,255,0,0,1]
|
|
||||||
sdata[2][3] = [0,255,0,0,1]
|
|
||||||
sdata[2][4] = [0,255,0,0,1]
|
|
||||||
sdata[2][6] = [0,255,0,0,1]
|
|
||||||
|
|
||||||
send_update()
|
|
||||||
exit()
|
|
||||||
|
|
||||||
|
|
||||||
# if not active, check if adjacent cell is active
|
# if not active, check if adjacent cell is active
|
||||||
if wdata[x][y][0] == 0 and has_active_neighb(x, y):
|
if wdata[x][y][0] == 0 and has_active_neighb(x, y):
|
||||||
|
@ -201,5 +189,9 @@ for t in range(60):
|
||||||
# wait to paint process next frame
|
# wait to paint process next frame
|
||||||
time.sleep(sleeptime/1000.0)
|
time.sleep(sleeptime/1000.0)
|
||||||
|
|
||||||
|
# end of iteration, restart
|
||||||
|
|
||||||
|
# end of main animation loop
|
||||||
|
|
||||||
# close socket
|
# close socket
|
||||||
UDPSock.close()
|
UDPSock.close()
|
||||||
|
|
|
@ -27,8 +27,6 @@ UDPSock.bind((outgoing_if, local_port))
|
||||||
# goes down or refuses connection
|
# goes down or refuses connection
|
||||||
#UDPSock.connect((remote_host, remote_port))
|
#UDPSock.connect((remote_host, remote_port))
|
||||||
|
|
||||||
segmentsfile = open('segments','r')
|
|
||||||
|
|
||||||
hash = "s2l\n<8<18 " # 10 bytes
|
hash = "s2l\n<8<18 " # 10 bytes
|
||||||
|
|
||||||
alpha = chr(255)
|
alpha = chr(255)
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
# s2llib.py
|
||||||
|
# Python utility functions for syndelights
|
||||||
|
|
||||||
|
from socket import *
|
||||||
|
import sys, time
|
||||||
|
#from copy import deepcopy
|
||||||
|
|
||||||
|
class syndelights_canvas:
|
||||||
|
"""Holds the state of the canvas to be sent"""
|
||||||
|
segments_in_window = 8
|
||||||
|
|
||||||
|
def __init__(self, hpc, zb, w, h, seg_wins, hs, hsp, ts, tsp, deblvl):
|
||||||
|
# get hash passcode and z-buffer depth
|
||||||
|
self.hash_passcode = hpc
|
||||||
|
self.zed_buffer = zb
|
||||||
|
|
||||||
|
# main window dimensions
|
||||||
|
self.width = w
|
||||||
|
self.height = h
|
||||||
|
|
||||||
|
# number of windows with segment displays
|
||||||
|
self.segmented_windows_num = seg_wins
|
||||||
|
|
||||||
|
# set servers and ports
|
||||||
|
self.host_server = hs
|
||||||
|
self.host_server_port = hsp
|
||||||
|
self.target_server = ts
|
||||||
|
self.target_server_port = tsp
|
||||||
|
|
||||||
|
# debugging
|
||||||
|
self.debug_level = deblvl
|
||||||
|
|
||||||
|
# make data structures for windows and segments
|
||||||
|
self.reset_windows(0,127,127,127, 255)
|
||||||
|
self.reset_segment_windows(0, 127, 127, 127, 255)
|
||||||
|
|
||||||
|
|
||||||
|
def reset_windows(self, state, red, green, blue, alpha):
|
||||||
|
self.window_data = []
|
||||||
|
for y in xrange(self.height):
|
||||||
|
self.window_data.append([0] * self.width)
|
||||||
|
for x in xrange(self.width):
|
||||||
|
self.window_data[y][x] = dict(s=state, r=red, g=green, b=blue, a=alpha)
|
||||||
|
|
||||||
|
def reset_segment_windows(self, state, red, green, blue, alpha):
|
||||||
|
self.segmented_windows = []
|
||||||
|
for w in xrange(self.segmented_windows_num):
|
||||||
|
self.segmented_windows.append([0] * self.segments_in_window)
|
||||||
|
for s in xrange(self.segments_in_window):
|
||||||
|
self.segmented_windows[w][s] = dict(s=state, r=red, g=green, b=blue, a=alpha)
|
||||||
|
|
||||||
|
# convert [r, g, b, a] into a 4 character string
|
||||||
|
def int2chr(self, rgba_dict):
|
||||||
|
return chr(int(rgba_dict["r"])) + chr(int(rgba_dict["g"])) + chr(int(rgba_dict["b"])) + chr(int(rgba_dict["a"]))
|
||||||
|
|
||||||
|
# draw the data object, send it to the target server
|
||||||
|
def draw(self):
|
||||||
|
# prep header with hash, z-buffer and new line (12 bytes)
|
||||||
|
data = self.hash_passcode + chr(self.zed_buffer) + "\n"
|
||||||
|
|
||||||
|
# package window data
|
||||||
|
for y in xrange(self.height):
|
||||||
|
for x in xrange(self.width):
|
||||||
|
data = data + self.int2chr( self.window_data[y][x] )
|
||||||
|
data = data + "\n"
|
||||||
|
|
||||||
|
# package segment data
|
||||||
|
for w in xrange(self.segmented_windows_num):
|
||||||
|
for s in xrange(self.segments_in_window):
|
||||||
|
data = data + self.int2chr( self.segmented_windows[w][s] )
|
||||||
|
data = data + "\n"
|
||||||
|
|
||||||
|
if self.debug_level > 2:
|
||||||
|
print data
|
||||||
|
|
||||||
|
# send the data through UDP to remote server
|
||||||
|
self.UDPSock.sendto(data, (self.target_server, self.target_server_port))
|
||||||
|
|
||||||
|
def setwin_xy_srgba_array(self, x, y, srgba):
|
||||||
|
self.window_data[y][x] = dict(s=srgba[0], r=srgba[1], g=srgba[2], b=srgba[3], a=srgba[4])
|
||||||
|
|
||||||
|
def setwin_xy_sval(self, x, y, col, val):
|
||||||
|
if col == 's':
|
||||||
|
self.window_data[y][x]['s'] = val
|
||||||
|
if col == 'r':
|
||||||
|
self.window_data[y][x]['r'] = val
|
||||||
|
if col == 'g':
|
||||||
|
self.window_data[y][x]['r'] = val
|
||||||
|
if col == 'b':
|
||||||
|
self.window_data[y][x]['r'] = val
|
||||||
|
if col == 'a':
|
||||||
|
self.window_data[y][x]['r'] = val
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.UDPSock = socket(AF_INET, SOCK_DGRAM)
|
||||||
|
self.UDPSock.bind((self.host_server, self.host_server_port))
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
self.UDPSock.close()
|
|
@ -0,0 +1,22 @@
|
||||||
|
from s2llib import *
|
||||||
|
import time
|
||||||
|
|
||||||
|
width = 12
|
||||||
|
height = 8
|
||||||
|
|
||||||
|
test = syndelights_canvas("s2l\n<8<18 ", 1, width, height, width, "127.0.0.1", 5001, "127.0.0.1", 4422, 3)
|
||||||
|
test = syndelights_canvas("s2l\n<8<18 ", 1, width, height, width, "127.0.0.1", 5001, "127.0.0.1", 4321, 3)
|
||||||
|
|
||||||
|
test.connect()
|
||||||
|
test.reset_windows(0, 0, 0, 0, 127)
|
||||||
|
test.reset_segment_windows(0, 62, 62, 62, 63)
|
||||||
|
|
||||||
|
|
||||||
|
for y in xrange(height):
|
||||||
|
for x in xrange(width):
|
||||||
|
test.setwin_xy_srgba_array(x, y, [0, 255, 0, 0, 127])
|
||||||
|
test.draw()
|
||||||
|
time.sleep(0.5)
|
||||||
|
test.setwin_xy_srgba_array(x, y, [0, 0, 0, 0, 127])
|
||||||
|
|
||||||
|
test.disconnect()
|
|
@ -173,7 +173,7 @@ void Server::listen()
|
||||||
void Server::send()
|
void Server::send()
|
||||||
{
|
{
|
||||||
|
|
||||||
const int length = 12 + HEIGHT*(WIDTH*CHANNELS+1) + SEGWIDTH*(SEGNUM*SEGCHANNELS+1);
|
const int length = HEADEROFFSET + HEIGHT*(WIDTH*CHANNELS+1) + SEGWIDTH*(SEGNUM*SEGCHANNELS+1);
|
||||||
static char data[length];
|
static char data[length];
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -188,10 +188,10 @@ void Server::send()
|
||||||
{
|
{
|
||||||
for(int k = 0; k < CHANNELS; k++)
|
for(int k = 0; k < CHANNELS; k++)
|
||||||
{
|
{
|
||||||
data[i*(WIDTH*CHANNELS+1) + j*CHANNELS + k] = frame.windows[i][j][k];
|
data[HEADEROFFSET + i*(WIDTH*CHANNELS+1) + j*CHANNELS + k] = frame.windows[i][j][k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data[i*(WIDTH*CHANNELS+1) + (WIDTH*CHANNELS)] = '\n';
|
data[HEADEROFFSET + i*(WIDTH*CHANNELS+1) + (WIDTH*CHANNELS)] = '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < SEGWIDTH; i++)
|
for(int i = 0; i < SEGWIDTH; i++)
|
||||||
|
@ -200,11 +200,11 @@ void Server::send()
|
||||||
{
|
{
|
||||||
for(int k = 0; k < SEGCHANNELS; k++)
|
for(int k = 0; k < SEGCHANNELS; k++)
|
||||||
{
|
{
|
||||||
data[HEIGHT*(WIDTH*CHANNELS+1) +
|
data[HEADEROFFSET + HEIGHT*(WIDTH*CHANNELS+1) +
|
||||||
i*(SEGNUM*SEGCHANNELS+1) + j*SEGCHANNELS + k] = frame.segments[i][j][k];
|
i*(SEGNUM*SEGCHANNELS+1) + j*SEGCHANNELS + k] = frame.segments[i][j][k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data[HEIGHT*(WIDTH*CHANNELS+1) +
|
data[HEADEROFFSET + HEIGHT*(WIDTH*CHANNELS+1) +
|
||||||
i*(SEGNUM*SEGCHANNELS+1) + (SEGNUM*SEGCHANNELS)] = '\n';
|
i*(SEGNUM*SEGCHANNELS+1) + (SEGNUM*SEGCHANNELS)] = '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue