5 CONFIG
= 'game_config.xml'
7 WINDOW_SIZE
= (640, 480)
8 WINDOW_CAPTION
= "Testing stuff"
11 BROADCAST_BIND
= 50031
21 MULTICAST
= '234.0.0.1'
27 SERVERREQUEST
= "i_want_server"
28 SERVEROFFER
= "Want_server?"
29 SERVERKILL
= "DIE_server!!"
30 YOUTHERE
= "you_there?"
31 IMHERE
= "yeah,i'm_here"
36 LIST
= "peoples_on_server"
37 SOMEONEJOINED
= "dude,someone_joined"
38 SOMEONELEFT
= "someone_left"
39 YOUROUT
= "get_lost_punk"
40 LETTER
= "listen_to_me"
41 SERVER_GONE
= 'its_gone'
51 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT
)
54 glTranslatef(-1.5, 0.0, -6.0)
57 glColor3f(1.0, 0.0, 0.0)
58 glVertex3f(0.0, 1.0, 0.0)
59 glColor3f(0.0, 1.0, 0.0)
60 glVertex3f(-1.0, -1.0, 0)
61 glColor3f(0.0, 0.0, 1.0)
62 glVertex3f(1.0, -1.0, 0)
65 glTranslatef(3.0, 0.0, 0.0)
67 glColor3f(0.5, 0.5, 1.0)
69 glVertex3f(-1.0, 1.0, 0)
70 glVertex3f(1.0, 1.0, 0)
71 glVertex3f(1.0, -1.0, 0)
72 glVertex3f(-1.0, -1.0, 0)
87 from xml
.dom
.minidom
import parse
, parseString
88 from threading
import Lock
92 from twisted
.internet
.protocol
import DatagramProtocol
93 from twisted
.internet
import reactor
94 from twisted
.internet
import task
100 from pgu
import gui
as pgui
106 from OpenGL
.GL
import *
108 from OpenGL
.GLU
import *
112 def getBroadcast(ip
):
116 print "getBroadcast(): Broadcast is reported to be", ip
119 reactor
.resolve('<broadcast>').addCallback(getBroadcast
)
121 the_event_receiver
= 0
130 self
.items_lock
= Lock()
134 return len(self
.items
)
138 self
.items_lock
.acquire()
139 the_item
= self
.items
.pop(0)
140 self
.items_lock
.release()
144 def addItem(self
, new_item
):
146 self
.items_lock
.acquire()
147 self
.items
.append(new_item
)
148 self
.items_lock
.release()
152 class EventReceiver(QueueLock
):
155 return self
.getItem()
156 def addEvent(self
, event
):
161 class CommandLine(QueueLock
):
163 def getCommand(self
):
164 return self
.getItem()
165 def addCommand(self
, command
):
166 self
.addItem(command
)
169 class Multicast(DatagramProtocol
):
171 def startProtocol(self
):
172 self
.transport
.joinGroup(MULTICAST
)
174 def datagramReceived(self
, datagram
, address
):
178 class Client(DatagramProtocol
):
180 def datagramReceived(self
, data
, (host
, port
)):
182 if data
[:len(YOUTHERE
)] == YOUTHERE
:
184 # print "Client.datagramReceived(): Recieved YOUTHERE, responding with IMHERE"
185 self
.transport
.write(IMHERE
, (host
, port
))
187 if data
[:len(SERVEROFFER
)] == SERVEROFFER
:
189 split_strings
= data
.split()
191 self
.servers
[split_strings
[2]] = (host
, int(split_strings
[1]))
193 event
= [SERVEROFFER
, {'server_name': split_strings
[2],
194 'server_address': self
.servers
[split_strings
[2]]}]
195 the_engine
.events
.addEvent(event
)
197 print "Client.datagramReceived(): Received SERVEROFFER"
199 if data
[:len(YOUREIN
)] == YOUREIN
:
201 if (host
, port
) == self
.requested_server
:
202 self
.current_server
= (host
, port
)
203 self
.requested_server
= ()
206 data
= {'server': self
.current_server
}
209 the_engine
.events
.addEvent(event
)
211 print "Client.datagramReceived(): Received YOUREIN, joined server"
215 if data
[:len(LIST
)] == LIST
:
217 print "Client.datagramReceived(): Received LIST"
219 split_strings
= data
.split()
223 for string
in split_strings
:
225 self
.members
.append(string
)
228 data
= {'names': self
.members
, 'server_address': (host
, port
)}
231 the_engine
.events
.addEvent(event
)
235 if data
[:len(SOMEONEJOINED
)] == SOMEONEJOINED
:
237 if (host
, port
) == self
.current_server
:
239 print "Client.datagramReceived(): Received SOMEONEJOINED"
243 for member
in self
.members
:
244 if member
== data
[len(SOMEONEJOINED
) + 1:]:
247 if left_member
== '':
248 self
.members
.append(data
[len(SOMEONEJOINED
) + 1:])
250 event
= [SOMEONEJOINED
]
251 data
= {'name': data
[len(SOMEONEJOINED
) + 1:]}
255 the_engine
.events
.addEvent(event
)
259 if data
[:len(SOMEONELEFT
)] == SOMEONELEFT
:
261 if (host
, port
) == self
.current_server
:
263 name
= data
[len(SOMEONELEFT
) + 1:]
265 if name
in self
.members
:
266 print "Client.datagramReceived(): Received SOMEONELEFT"
268 self
.members
.remove(name
)
270 event
= [SOMEONELEFT
]
271 data
= {'name': name
}
275 the_engine
.events
.addEvent(event
)
278 print "Client.datagramReceived(): Received SOMEONELEFT, but", name
, "not present in roster"
282 if data
[:len(YOUROUT
)] == YOUROUT
:
284 if (host
, port
) == self
.current_server
:
286 print "Client.datagramReceived(): Recieved YOUROUT"
288 self
.current_server
= ()
294 the_engine
.events
.addEvent(event
)
298 if data
[:len(LETTER
)] == LETTER
:
300 if (host
, port
) == self
.current_server
:
301 print "Client.datagramReceived(): Received LETTER"
303 split_strings
= data
.split(':')
305 message
= data
[data
.find(':', len(LETTER
) + 1) + 1:]
306 message_origin
= split_strings
[1]
309 data
= {'message': message
, 'origin': message_origin
}
312 the_engine
.events
.addEvent(event
)
316 if data
[:len(IMHERE
)] == IMHERE
:
318 if (host
, port
) == self
.current_server
:
319 print "Client.datagramReceived(): Received IMHERE from server"
321 self
.server_request
= 0
325 def init(self
, params
):
329 self
.current_server
= ()
330 self
.requested_server
= ()
337 def serverRequest(self
):
339 if self
.current_server
!= ():
341 if self
.server_request
> SERVER_TIMEOUT
:
342 the_engine
.events
.addEvent([SERVER_GONE
, {}])
343 self
.current_server
= ()
346 self
.server_request
+= 1
347 self
.transport
.write(YOUTHERE
, self
.current_server
)
351 def executeCommand(self
, command
, data
):
353 reactor
.callFromThread(self
.executeThreadedCommand
, command
, data
)
357 def executeThreadedCommand(self
, command
, data
):
358 if command
== SERVERKILL
:
360 if self
.current_server
!= ():
362 message
= ''.join([SERVERKILL
, ' '])
364 if data
.has_key('password'):
365 message
= ''.join([message
, data
['password']])
367 self
.transport
.write(message
, self
.current_server
)
369 if command
== SERVERREQUEST
:
371 message
= ''.join([SERVERREQUEST
, ' ', str(self
.params
['message_port'])])
373 the_multicast
.transport
.write(message
, (MULTICAST
, self
.params
['broadcast_port']))
374 # self.transport.write(message, ('255.255.255.255', self.params['broadcast_port']))
376 if command
== GETLIST
:
380 if data
.has_key('server'):
382 if self
.servers
.has_key(data
['server']):
383 self
.transport
.write(message
, self
.servers
[data
['server']])
387 if self
.current_server
!= ():
388 self
.transport
.write(message
, self
.current_server
)
392 if self
.current_server
!= ():
396 self
.transport
.write(message
, self
.current_server
)
398 self
.current_server
= ()
400 if command
== LETTER
:
402 if self
.current_server
!= ():
404 message
= ''.join([LETTER
, ':'])
406 for dest
in data
['destinations']:
407 if dest
in self
.members
:
408 message
= ''.join([message
, ' ' , dest
])
410 message
= ''.join([message
, ':', data
['message']])
412 self
.transport
.write(message
, self
.current_server
)
414 if command
== WANTIN
:
416 if data
.has_key('server'):
417 if self
.servers
.has_key(data
['server']):
419 self
.transport
.write(''.join([WANTIN
, ' ', self
.params
['name']]),
420 self
.servers
[data
['server']])
421 self
.current_server
= ()
422 self
.requested_server
= self
.servers
[data
['server']]
428 def __init__(self
, config
):
436 video_flags
= OPENGL|DOUBLEBUF
439 self
.display
= pygame
.display
.set_mode(config
['window_size'], video_flags
)
441 self
.font
= pygame
.font
.SysFont("default", 18)
442 self
.fontBig
= pygame
.font
.SysFont("default", 24)
443 self
.fontSub
= pygame
.font
.SysFont("default", 20)
444 self
.theme
= pgui
.Theme(['test_theme', 'gray', 'default'])
445 # self.theme = pgui.Theme('gray')
446 # self.theme = pgui.Theme('default')
448 self
.resize((config
['window_size']))
450 glShadeModel(GL_SMOOTH
)
451 glClearColor(self
.config
['background_color'][0],
452 self
.config
['background_color'][1],
453 self
.config
['background_color'][2],
454 self
.config
['background_color'][3])
456 glEnable(GL_DEPTH_TEST
)
457 glDepthFunc(GL_LEQUAL
)
458 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
)
460 pygame
.display
.set_caption(config
['window_title'])
462 self
.gui_screen
= lamina
.LaminaScreenSurface()
464 self
.app
= pgui
.App(theme
=self
.theme
)
465 self
.app
._screen
= self
.gui_screen
.surf
466 self
.main_container
= pgui
.Container(width
=config
['window_size'][0])
470 self
.events
= EventReceiver()
472 # self.files is a map of filename to file
475 # {parent, [children], {object_defs},
476 # {menu_defs}, {object_instances}, {menu_instances}}
480 for file in listdir(self
.config
['pack_dir']):
481 if (is_zipfile(os
.path
.join(self
.config
['pack_dir'], file))):
482 self
.zipfiles
.append(ZipFile(os
.path
.join(self
.config
['pack_dir'], file)))
484 self
.running
= self
.addFile(self
.config
['init'], '')
485 self
.app
.init(self
.main_container
)
487 self
.ticks
= pygame
.time
.get_ticks()
490 if self
.running
== 0:
491 print "Engine.__init__(): Failed adding initial file"
493 self
.message_boxen
= []
501 self
.process_events()
505 pygame
.display
.flip()
511 self
.oldticks
= self
.ticks
512 self
.ticks
= pygame
.time
.get_ticks()
516 self
.fps
= (self
.frames
* 1000) / (self
.ticks
- self
.oldticks
) / 1000
518 pygame
.display
.set_caption(''.join([self
.config
['window_title'], ' ', str(self
.fps
)]))
522 def process_events(self
):
526 for e
in pygame
.event
.get():
529 print "Should be quitting..."
534 change
= self
.app
.update(self
.gui_screen
.surf
)
537 self
.gui_screen
.refresh(change
)
539 new_event
= self
.convertEvent(e
)
540 self
.events
.addEvent(new_event
)
545 if self
.events
.size():
546 new_event
= self
.events
.getEvent()
554 for file in self
.files
.keys():
556 for name
in self
.files
[file]['object_instances'].keys():
558 self
.files
[file]['object_instances'][name
].event(new_event
[0], new_event
[1])
562 def convertEvent(self
, e
):
569 if e
.type == ACTIVEEVENT
:
570 data
['gain'] = e
.gain
571 data
['state'] = e
.state
573 if e
.type == KEYDOWN
:
574 data
['unicode'] = e
.unicode
582 if e
.type == MOUSEMOTION
:
585 data
['buttons'] = e
.buttons
587 if e
.type == MOUSEBUTTONUP
:
589 data
['button'] = e
.button
591 if e
.type == MOUSEBUTTONDOWN
:
593 data
['button'] = e
.button
595 if e
.type == JOYAXISMOTION
:
597 data
['axis'] = e
.axis
598 data
['value'] = e
.value
600 if e
.type == JOYBALLMOTION
:
602 data
['ball'] = e
.ball
605 if e
.type == JOYHATMOTION
:
608 data
['value'] = e
.value
610 if e
.type == JOYBUTTONUP
:
612 data
['button'] = e
.button
614 if e
.type == JOYBUTTONDOWN
:
616 data
['button'] = e
.button
618 if e
.type == VIDEORESIZE
:
619 data
['size'] = e
.size
623 if e
.type == VIDEOEXPOSE
:
626 if e
.type == USEREVENT
:
627 data
['code'] = e
.code
631 if e
.type == QUIT
: type = "QUIT"
632 if e
.type == ACTIVEEVENT
: type = "ACTIVEEVENT"
633 if e
.type == KEYDOWN
: type = "KEYDOWN"
634 if e
.type == KEYUP
: type = "KEYUP"
635 if e
.type == MOUSEMOTION
: type = "MOUSEMOTION"
636 if e
.type == MOUSEBUTTONUP
: type = "MOUSEBUTTONUP"
637 if e
.type == MOUSEBUTTONDOWN
: type = "MOUSEBUTTONDOWN"
638 if e
.type == JOYAXISMOTION
: type = "JOYAXISMOTION"
639 if e
.type == JOYBALLMOTION
: type = "JOYBALLMOTION"
640 if e
.type == JOYHATMOTION
: type = "JOYHATMOTION"
641 if e
.type == JOYBUTTONUP
: type = "JOYBUTTONUP"
642 if e
.type == JOYBUTTONDOWN
: type = "JOYBUTTONDOWN"
643 if e
.type == VIDEORESIZE
: type = "VIDEORESIZE"
644 if e
.type == VIDEOEXPOSE
: type = "VIDEOEXPOSE"
645 if e
.type == USEREVENT
: type = "USEREVENT"
651 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT
)
658 self
.gui_screen
.display()
660 def resize(self
, (width
, height
)):
663 glViewport(0, 0, width
, height
)
664 glMatrixMode(GL_PROJECTION
)
666 gluPerspective(45, 1.0*width
/height
, 0.1, 100.0)
667 glMatrixMode(GL_MODELVIEW
)
672 def addFile(self
, filename
, parent
):
674 # Because I have alot of nesting in this function,
675 # I am using 2 space formatting
677 for zipfile
in self
.zipfiles
:
679 for file in zipfile
.namelist():
681 if (file == filename
):
682 dom
= parseString(zipfile
.read(file))
684 object_instances_d
= []
687 if dom
.childNodes
[0].nodeName
== 'game':
688 self
.files
[filename
] = {
692 'object_instances': {},
693 'menu_instances': {},
696 for node
in dom
.childNodes
[0].childNodes
:
698 if (node
.nodeName
== 'def'):
700 for sub_node
in node
.childNodes
:
702 if (sub_node
.nodeName
== 'object'):
706 for suber_node
in sub_node
.childNodes
:
708 if (suber_node
.nodeName
== 'name'):
709 if len(suber_node
.childNodes
):
710 temp_object_def
['name'] = suber_node
.childNodes
[0].nodeValue
712 if (suber_node
.nodeName
== 'script'):
713 if len(suber_node
.childNodes
):
714 temp_object_def
['script'] = suber_node
.childNodes
[0].nodeValue
716 if (suber_node
.nodeName
== 'tangible'):
717 if len(suber_node
.childNodes
):
718 temp_object_def
['tangible'] = suber_node
.childNodes
[0].nodeValue
720 if (suber_node
.nodeName
== 'type'):
721 if len(suber_node
.childNodes
):
722 temp_object_def
['type'] = suber_node
.childNodes
[0].nodeValue
724 self
.files
[filename
]['object_defs'][temp_object_def
['name']] = temp_object_def
727 if (sub_node
.nodeName
== 'menu'):
730 temp_menu_def
['elements'] = {}
732 temp_element_set
= {}
734 for suber_node
in sub_node
.childNodes
:
736 if (suber_node
.nodeName
== 'name'):
737 temp_menu_def
['name'] = suber_node
.childNodes
[0].nodeValue
739 if (suber_node
.nodeName
== 'elements'):
741 for suberer_node
in suber_node
.childNodes
:
743 if (suberer_node
.nodeType
!= 3 and suberer_node
.nodeType
!= 8):
744 if (suberer_node
.hasAttribute('name')):
745 temp_element_set
['name'] = suberer_node
.getAttribute('name')
747 if (suberer_node
.hasAttribute('x')):
748 temp_element_set
['x'] = int(suberer_node
.getAttribute('x'))
750 if (suberer_node
.hasAttribute('y')):
751 temp_element_set
['y'] = int(suberer_node
.getAttribute('y'))
753 if (suberer_node
.hasAttribute('width')):
754 temp_element_set
['width'] = int(suberer_node
.getAttribute('width'))
756 if (suberer_node
.hasAttribute('height')):
757 temp_element_set
['height'] = int(suberer_node
.getAttribute('height'))
759 if (suberer_node
.hasAttribute('parent')):
760 temp_element_set
['parent'] = suberer_node
.getAttribute('parent')
762 if (suberer_node
.hasAttribute('target')):
763 temp_element_set
['target'] = suberer_node
.getAttribute('target')
765 if (suberer_node
.hasAttribute('text')):
766 temp_element_set
['text'] = suberer_node
.getAttribute('text')
768 temp_element_set
['type'] = suberer_node
.nodeName
769 temp_menu_def
['elements'][temp_element_set
['name']] = temp_element_set
770 temp_element_set
= {}
772 self
.files
[filename
]['menu_defs'][temp_menu_def
['name']] = temp_menu_def
775 temp_element_set
= {}
777 if (node
.nodeName
== 'instance'):
779 for sub_node
in node
.childNodes
:
781 if (sub_node
.nodeName
== 'object'):
782 object_instances_d
.append(sub_node
.childNodes
[0].nodeValue
)
784 if (sub_node
.nodeName
== 'menu'):
785 menu_instances
.append(sub_node
.childNodes
[0].nodeValue
)
788 self
.files
[parent
]['children'].append(filename
)
789 self
.files
[filename
]['parent'] = parent
793 for menuname
, menu_data
in self
.files
[filename
]['menu_defs'].iteritems():
794 self
.files
[filename
]['menu_instances'][menuname
] = Menu(menu_def
=menu_data
)
796 for menuname
in menu_instances
:
797 if (self
.files
[filename
]['menu_instances'].has_key(menuname
)):
798 self
.files
[filename
]['menu_instances'][menuname
].show()
800 for file in self
.files
.keys():
801 if self
.files
[file]['menu_instances'].has_key(menuname
):
802 self
.files
[file]['menu_instances'][menuname
].show()
804 for objectname
in object_instances_d
:
805 self
.addObject(objectname
)
809 # ending 2-space formatting
811 def removeFile(self
, filename
):
813 if (self
.files
.has_key(filename
)):
815 for child
in self
.files
[filename
]['children']:
816 self
.removeFile(child
)
818 del self
.files
[filename
]['children']
820 parent
= self
.files
[filename
]['parent']
822 self
.files
[parent
]['children'].pop(self
.files
[parent
]['children'].index(filename
))
824 del self
.files
[filename
]
828 def getVisibleMenus(self
):
832 for file, contents
in self
.files
.iteritems():
833 for name
, menu
in contents
['menu_instances'].iteritems():
839 def hideAllMenus(self
):
841 for file, contents
in self
.files
.iteritems():
842 for name
, menu
in contents
['menu_instances'].iteritems():
847 def showMenu(self
, menu_name
):
849 for file, contents
in self
.files
.iteritems():
850 for name
, menu
in contents
['menu_instances'].iteritems():
851 if contents
['menu_instances'].has_key(menu_name
):
852 contents
['menu_instances'][menu_name
].show()
856 def hideMenu(self
, menu_name
):
858 for file, contents
in self
.files
:
859 for name
, menu
in contents
['menu_instances'].iteritems():
860 if contents
['menu_instances'].has_key(menu_name
):
861 contents
['menu_instances'][menu_name
].hide()
865 def setMenu(self
, menu_name
):
868 self
.showMenu(menu_name
)
872 def addObject(self
, objectname
):
874 for file in self
.files
.keys():
875 if self
.files
[file]['object_defs'].has_key(objectname
):
876 self
.files
[file]['object_instances'][objectname
] = GameObject(
877 self
.files
[file]['object_defs'][objectname
])
881 def removeObject(self
, objectname
):
883 for file in self
.files
.keys():
884 if self
.files
[file]['object_defs'].has_key(objectname
):
885 del self
.files
[file]['object_instances'][objectname
]
889 def addListItem(self
, menuname
, item
, data
, dvalue
):
891 for file in self
.files
:
892 if self
.files
[file]['menu_instances'].has_key(menuname
):
893 if self
.files
[file]['menu_instances'][menuname
].widgets
.has_key(item
):
894 the_widget
= self
.files
[file]['menu_instances'][menuname
].widgets
[item
]
896 the_widget
.add(data
.encode(), value
=dvalue
)
902 def clearListItem(self
, menuname
, item
):
904 for file in self
.files
:
905 if self
.files
[file]['menu_instances'].has_key(menuname
):
906 if self
.files
[file]['menu_instances'][menuname
].widgets
.has_key(item
):
907 the_widget
= self
.files
[file]['menu_instances'][menuname
].widgets
[item
]
915 def removeListItem(self
, menuname
, item
, value
):
917 for file in self
.files
:
918 if self
.files
[file]['menu_instances'].has_key(menuname
):
919 if self
.files
[file]['menu_instances'][menuname
].widgets
.has_key(item
):
920 the_widget
= self
.files
[file]['menu_instances'][menuname
].widgets
[item
]
922 the_widget
.remove(value
)
928 def getListValue(self
, menuname
, item
):
930 for file in self
.files
:
931 if self
.files
[file]['menu_instances'].has_key(menuname
):
933 if self
.files
[file]['menu_instances'][menuname
].widgets
.has_key(item
):
934 the_widget
= self
.files
[file]['menu_instances'][menuname
].widgets
[item
]
936 return the_widget
.value
940 def getEditboxValue(self
, menuname
, item
):
942 for file in self
.files
:
943 if self
.files
[file]['menu_instances'].has_key(menuname
):
945 if self
.files
[file]['menu_instances'][menuname
].widgets
.has_key(item
):
946 the_widget
= self
.files
[file]['menu_instances'][menuname
].widgets
[item
]
948 return the_widget
.value
950 the_widget
= self
.files
[file]['menu_instances'][menuname
].widgets
[item
]
952 return the_widget
.value
954 def setEditboxValue(self
, menuname
, item
, new_value
):
956 for file in self
.files
:
957 if self
.files
[file]['menu_instances'].has_key(menuname
):
959 if self
.files
[file]['menu_instances'][menuname
].widgets
.has_key(item
):
960 the_widget
= self
.files
[file]['menu_instances'][menuname
].widgets
[item
]
962 the_widget
.value
= new_value
966 def showMessageBox(self
, message
, title
, width
, height
):
968 # Modify width and height to your liking
971 the_engine
.messageBox(title
, message
)
975 def getImage(self
, filename
):
977 the_buf
= pygame
.image
.load(self
.getStringIOFile(filename
))
981 def getStringIOFile(self
, filename
):
983 for zip_file
in self
.zipfiles
:
984 for file in zip_file
.namelist():
986 if (filename
== file):
988 the_string_io
= StringIO
.StringIO()
989 print >>the_string_io
, zip_file
.read(file)
990 the_string_io
.seek(0)
995 def getStringData(self
, filename
):
996 for zip_file
in self
.zipfiles
:
997 for file in zip_file
.namelist():
999 if (filename
== file):
1000 return zip_file
.read(file)
1003 def killThreadGame(self
):
1011 reactor
.callFromThread(self
.killThreadGame
)
1017 def __init__(self
, menu_def
):
1019 self
.menu_def
= menu_def
1022 for name
, element
in menu_def
['elements'].iteritems():
1024 multiplier_x
= float(the_engine
.config
['window_size'][0]) / 100.00
1025 multiplier_y
= float(the_engine
.config
['window_size'][1]) / 100.00
1027 dx
= float(element
['x']) * multiplier_x
1028 dy
= float(element
['y']) * multiplier_y
1030 dwidth
= float(element
['width']) * multiplier_x
1031 dheight
= float(element
['height']) * multiplier_y
1033 if (element
['type'] == 'button'):
1034 self
.widgets
[name
] = pgui
.Button(element
['text'].encode(), width
=dwidth
, height
=dheight
)
1035 self
.widgets
[name
].connect(pgui
.CLICK
, self
.clicked
, name
)
1037 if (element
['type'] == 'image'):
1038 self
.widgets
[name
] = pgui
.Image(the_engine
.getImage(element
['text']))
1040 if (element
['type'] == 'label'):
1041 self
.widgets
[name
] = pgui
.Label(element
['text'])
1043 if (element
['type'] == 'listbox'):
1044 self
.widgets
[name
] = pgui
.List(width
=dwidth
, height
=dheight
)
1045 self
.widgets
[name
].connect(pgui
.CLICK
, self
.clicked
, name
)
1047 if (element
['type'] == 'editbox'):
1048 self
.widgets
[name
] = pgui
.Input(value
=element
['text'], width
=dwidth
)
1049 self
.widgets
[name
].connect(pgui
.KEYDOWN
, self
.key_pressed
, name
)
1050 self
.widgets
[name
].connect(pgui
.KEYUP
, self
.key_up
, name
)
1052 if (self
.widgets
.has_key(name
)):
1053 self
.widgets
[name
].resize(width
=dwidth
, height
=dheight
)
1055 print "Menu.__init__(): Widget type", element
['type'], " not implemented yet, skipping."
1063 multiplier_x
= float(the_engine
.config
['window_size'][0]) / 100.00
1064 multiplier_y
= float(the_engine
.config
['window_size'][1]) / 100.00
1066 if (self
.hidden
== 1):
1067 for name
, element
in self
.menu_def
['elements'].iteritems():
1068 dx
= float(element
['x']) * multiplier_x
1069 dy
= float(element
['y']) * multiplier_y
1071 if self
.widgets
.has_key(name
):
1072 the_engine
.main_container
.add(self
.widgets
[name
], dx
, dy
)
1082 if (self
.hidden
!= 1):
1083 for name
, element
in self
.menu_def
['elements'].iteritems():
1085 if (self
.widgets
.has_key(name
)):
1086 the_engine
.main_container
.remove(self
.widgets
[name
])
1092 def clicked(self
, widget
, _event
):
1094 if self
.menu_def
['elements'].has_key(widget
):
1096 if self
.menu_def
['elements'][widget
]['target'] != '':
1097 exec(self
.menu_def
['elements'][widget
]['target'])
1099 the_engine
.events
.addEvent(['WIDGET_CLICKED',
1101 'menu_name': self
.menu_def
['name'],
1102 event
: the_engine
.convertEvent(_event
)}])
1106 def key_pressed(self
, widget
, _event
):
1108 if self
.menu_def
['elements'].has_key(widget
):
1110 new_event
= the_engine
.convertEvent(_event
)
1112 the_engine
.events
.addEvent(['KEYDOWN',
1114 'menu_name': self
.menu_def
['name'],
1115 'event': new_event
}])
1119 def key_up(self
, widget
, _event
):
1121 if self
.menu_def
['elements'].has_key(widget
):
1123 the_engine
.events
.addEvent(['KEYUP',
1125 'menu_name': self
.menu_def
['name'],
1126 event
: the_engine
.convertEvent(_event
)}])
1130 class MessageBox(pgui
.Dialog
):
1132 def __init__(self
, title
, message
):
1134 self
.title
= pgui
.Label(title
)
1135 self
.main
= pgui
.Label(message
)
1146 def __init__(self
, dmold
):
1149 global the_functions
1152 if self
.mold
['script'] != '':
1156 the_file
= the_engine
.getStringData(self
.mold
['script'])
1161 self
.my_functions
= the_functions
1165 def event(self
, event
, data
):
1167 if self
.my_functions
.has_key(event
):
1169 self
.my_functions
[event
](data
)
1174 # parse command line stuff
1176 if (len(sys
.argv
) > 1):
1177 config
= sys
.argv
[1]
1179 print "main(): No config specified, using", CONFIG
1182 configuration
= parse_config(config
)
1184 if (configuration
.has_key('error') and configuration
['error']):
1185 print "main(): Error in parsing config."
1187 the_event_receiver
= EventReceiver()
1189 global client_params
1190 client_params
= {'broadcast_port':configuration
['broadcast_port'],
1191 'broadcast_bind':configuration
['broadcast_bind'],
1192 'message_port':configuration
['message_port'],
1193 'name':configuration
['name'],
1194 'echo_time': configuration
['echo_time']}
1199 the_engine
= Engine(configuration
)
1201 the_client
= Client()
1202 the_client_thread
= threading
.Thread(target
=run_net
)
1204 the_client
.server_request
= 0
1206 the_client
.init(client_params
)
1208 the_client_thread
.start()
1211 the_engine
.killGame()
1215 the_client_thread
.join()
1221 global client_params
1222 global the_multicast
1224 the_multicast
= Multicast()
1225 config
= client_params
1227 reactor
.listenMulticast(config
['broadcast_bind'], the_multicast
)
1228 reactor
.listenUDP(config
['message_port'], the_client
)
1230 echo_request
= task
.LoopingCall(the_client
.serverRequest
)
1232 if client_params
['echo_time'] != None:
1233 echo_request
.start(client_params
['echo_time'])
1235 print "run_net(): No ECHO_TIME specified, using default of", ECHO_TIME
1236 echo_request
.start(ECHO_TIME
)
1238 reactor
.run(installSignalHandlers
=0)
1242 def parse_config(filename
):
1243 results
= {'error': 1}
1245 if (exists(filename
)):
1246 dom
= parse(filename
)
1248 print "parse_config():", filename
, "doesn't exist."
1251 results
= {'window_title': None,
1256 'message_port': None,
1257 'broadcast_port': None,
1258 'broadcast_bind': None,
1260 'background_color': None,
1261 'window_size': None,
1267 if (dom
.childNodes
[0].nodeName
== 'config'):
1268 for node
in dom
.childNodes
[0].childNodes
:
1270 if (node
.nodeName
== 'window_title'):
1271 results
['window_title'] = node
.childNodes
[0].nodeValue
1273 if (node
.nodeName
== 'log'):
1274 results
['log'] = node
.childNodes
[0].nodeValue
1276 if (node
.nodeName
== 'name'):
1277 results
['name'] = node
.childNodes
[0].nodeValue
1279 if (node
.nodeName
== 'font'):
1280 results
['font'] = node
.childNodes
[0].nodeValue
1282 if (node
.nodeName
== 'init'):
1283 results
['init'] = node
.childNodes
[0].nodeValue
1285 if (node
.nodeName
== 'message_port'):
1286 results
['message_port'] = int(node
.childNodes
[0].nodeValue
)
1288 if (node
.nodeName
== 'broadcast_port'):
1289 results
['broadcast_port'] = int(node
.childNodes
[0].nodeValue
)
1291 if (node
.nodeName
== 'broadcast_bind'):
1292 results
['broadcast_bind'] = int(node
.childNodes
[0].nodeValue
)
1294 if (node
.nodeName
== 'fullscreen'):
1295 results
['fullscreen'] = int(node
.childNodes
[0].nodeValue
)
1297 if (node
.nodeName
== 'background_color'):
1299 string_parts
= node
.childNodes
[0].nodeValue
.split()
1300 results
['background_color'] = [float(string_parts
[0]), float(string_parts
[1])]
1301 results
['background_color'].append(float(string_parts
[2]))
1302 results
['background_color'].append(float(string_parts
[3]))
1304 if (node
.nodeName
== 'window_size'):
1306 string_parts
= node
.childNodes
[0].nodeValue
.split()
1307 results
['window_size'] = ((int(string_parts
[0]), int(string_parts
[1])))
1309 if (node
.nodeName
== 'gravity'):
1311 string_parts
= node
.childNodes
[0].nodeValue
.split()
1312 results
['gravity'] = [float(string_parts
[0]), float(string_parts
[1])]
1313 results
['gravity'].append(float(string_parts
[2]))
1315 if (node
.nodeName
== 'step_size'):
1316 results
['step_size'] = float(node
.childNodes
[0].nodeValue
)
1318 if (node
.nodeName
== 'pack_dir'):
1319 results
['pack_dir'] = node
.childNodes
[0].nodeValue
1321 if (node
.nodeName
== 'echo_time'):
1322 results
['echo_time'] = int(node
.childNodes
[0].nodeValue
)
1324 results
['error'] = 0
1328 if __name__
== '__main__':