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
|
||||
remote_port = 4422
|
||||
# port to frameserver
|
||||
#remote_port = 4321
|
||||
remote_port = 4321
|
||||
|
||||
# TODO: autodetect interface address for remote application
|
||||
outgoing_if = "127.0.0.1"
|
||||
|
@ -56,6 +56,9 @@ frequency = 1000 / sleeptime # frames per second
|
|||
|
||||
# function resets map to zero
|
||||
def set_wdata(r, g, b):
|
||||
global wdata
|
||||
wdata = []
|
||||
|
||||
for x in xrange(width):
|
||||
wdata.append([0] * height)
|
||||
for y in xrange(height):
|
||||
|
@ -80,6 +83,21 @@ def i2c(rgba):
|
|||
# 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]))
|
||||
|
||||
# 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
|
||||
def send_update():
|
||||
#zero out the data buffer
|
||||
|
@ -105,101 +123,75 @@ def send_update():
|
|||
# send the data packet to remote host
|
||||
UDPSock.sendto(data,(remote_host,remote_port))
|
||||
|
||||
# initialize map
|
||||
set_wdata(67,67,67)
|
||||
set_sdata(0,0,255)
|
||||
# main loop
|
||||
while True:
|
||||
# reset/initialize map
|
||||
set_wdata(67,67,67)
|
||||
set_sdata(255,255,255)
|
||||
|
||||
# set start seed
|
||||
# get random location
|
||||
rx = randint(0, width - 1)
|
||||
ry = randint(0, height - 1)
|
||||
wdata[rx][ry] = [1,1,0,0,1]
|
||||
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
|
||||
for t in range(60):
|
||||
|
||||
# push update to clients
|
||||
send_update()
|
||||
|
||||
# create CA buffer
|
||||
data_buffer = deepcopy(wdata)
|
||||
|
||||
for y in xrange(height):
|
||||
for x in xrange(width):
|
||||
# if cell is active, increase its rating/value
|
||||
if wdata[x][y][0] > 0:
|
||||
# change the state of the cell
|
||||
data_buffer[x][y][0] += 10
|
||||
|
||||
# assign stat to red colour
|
||||
data_buffer[x][y][1] = data_buffer[x][y][0]
|
||||
|
||||
# check we don't go too high
|
||||
if data_buffer[x][y][0] > 127:
|
||||
data_buffer[x][y][1] = 127
|
||||
# assign stat to green colour
|
||||
data_buffer[x][y][2] = data_buffer[x][y][0] - 127
|
||||
|
||||
if data_buffer[x][y][0] > 255:
|
||||
data_buffer[x][y][2] = 127
|
||||
# assign stat to blue colour
|
||||
data_buffer[x][y][3] = data_buffer[x][y][0] - 255
|
||||
|
||||
if data_buffer[x][y][0] > 383:
|
||||
data_buffer[x][y][3] = 127
|
||||
|
||||
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()
|
||||
# set start seed
|
||||
# get random location
|
||||
rx = randint(0, width - 1)
|
||||
ry = randint(0, height - 1)
|
||||
wdata[rx][ry] = [1,1,0,0,1]
|
||||
# print "origin(" + str(rx) + "," + str(ry) + ")"
|
||||
|
||||
# main logic loop
|
||||
for t in range(23):
|
||||
|
||||
# push update to clients
|
||||
send_update()
|
||||
|
||||
# if not active, check if adjacent cell is active
|
||||
if wdata[x][y][0] == 0 and has_active_neighb(x, y):
|
||||
# activate and colour
|
||||
data_buffer[x][y][0] = 1
|
||||
data_buffer[x][y][1] = 1
|
||||
data_buffer[x][y][2] = 0
|
||||
data_buffer[x][y][3] = 0
|
||||
# create CA buffer
|
||||
data_buffer = deepcopy(wdata)
|
||||
|
||||
for y in xrange(height):
|
||||
for x in xrange(width):
|
||||
# if cell is active, increase its rating/value
|
||||
if wdata[x][y][0] > 0:
|
||||
# change the state of the cell
|
||||
data_buffer[x][y][0] += 16
|
||||
|
||||
# assign stat to red colour
|
||||
data_buffer[x][y][1] = data_buffer[x][y][0]
|
||||
|
||||
# check we don't go too high
|
||||
# if the state is over 127, reset red
|
||||
if data_buffer[x][y][0] > 127:
|
||||
# assign max stat to red colour
|
||||
data_buffer[x][y][1] = 0
|
||||
# assign stat to green colour
|
||||
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:
|
||||
# assign max stat to green colour
|
||||
data_buffer[x][y][2] = 0
|
||||
# assign stat to blue colour
|
||||
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:
|
||||
data_buffer[x][y][3] = data_buffer[x][y][0]%128
|
||||
|
||||
# if not active, check if adjacent cell is active
|
||||
if wdata[x][y][0] == 0 and has_active_neighb(x, y):
|
||||
# activate and colour
|
||||
data_buffer[x][y][0] = 1
|
||||
data_buffer[x][y][1] = 1
|
||||
data_buffer[x][y][2] = 0
|
||||
data_buffer[x][y][3] = 0
|
||||
|
||||
|
||||
# set wdata to new buffer
|
||||
wdata = data_buffer
|
||||
# set wdata to new buffer
|
||||
wdata = data_buffer
|
||||
|
||||
# wait to paint process next frame
|
||||
time.sleep(sleeptime/1000.0)
|
||||
# wait to paint process next frame
|
||||
time.sleep(sleeptime/1000.0)
|
||||
|
||||
# end of iteration, restart
|
||||
|
||||
# end of main animation loop
|
||||
|
||||
# close socket
|
||||
UDPSock.close()
|
||||
|
|
|
@ -27,8 +27,6 @@ UDPSock.bind((outgoing_if, local_port))
|
|||
# goes down or refuses connection
|
||||
#UDPSock.connect((remote_host, remote_port))
|
||||
|
||||
segmentsfile = open('segments','r')
|
||||
|
||||
hash = "s2l\n<8<18 " # 10 bytes
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
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];
|
||||
|
||||
while(1)
|
||||
|
@ -188,10 +188,10 @@ void Server::send()
|
|||
{
|
||||
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++)
|
||||
|
@ -200,11 +200,11 @@ void Server::send()
|
|||
{
|
||||
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];
|
||||
}
|
||||
}
|
||||
data[HEIGHT*(WIDTH*CHANNELS+1) +
|
||||
data[HEADEROFFSET + HEIGHT*(WIDTH*CHANNELS+1) +
|
||||
i*(SEGNUM*SEGCHANNELS+1) + (SEGNUM*SEGCHANNELS)] = '\n';
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue