I'm getting network syncing working.
[krufty_fps.git] / more_twisted.py
blob868e766d663fab62f47eec2e86d26ca0d9745a92
1 7#!/usr/bin/python
3 # PyOpenGL + Pygame
5 CONFIG = 'game_config.xml'
7 WINDOW_SIZE = (640, 480)
8 WINDOW_CAPTION = "Testing stuff"
10 BROADCAST = 50030
11 BROADCAST_BIND = 50031
12 MESSAGE = 40030
14 BUFSIZE = 120
16 TIMEOUT = .1
18 BROADCAST = ''
19 MULTICAST = '234.0.0.1'
21 # this will change
23 SERVERREQUEST = "i_want_server"
24 SERVEROFFER = "Want_server?"
25 SERVERKILL = "DIE_server!!"
26 YOUTHERE = "you_there?"
27 IMHERE = "yeah,i'm_here"
28 WANTIN = "i_want_in"
29 YOUREIN = "urine"
30 IMOUT = "i_leave"
31 GETLIST = "get_list"
32 LIST = "peoples_on_server"
33 SOMEONEJOINED = "dude,someone_joined"
34 SOMEONELEFT = "someone_left"
35 YOUROUT = "get_lost_punk"
36 LETTER = "listen_to_me"
38 the_functions = {}
39 in_script = 0
41 import os, sys
42 from os import *
43 from os.path import *
45 import threading
46 from socket import *
47 from xml.dom.minidom import parse, parseString
48 from threading import Lock
49 from signal import *
50 from zipfile import *
52 from twisted.internet.protocol import DatagramProtocol
53 from twisted.internet import reactor
54 from twisted.internet import task
56 import pygame
57 from pygame import *
59 import pgu
60 from pgu import gui as pgui
62 import lamina
64 import OpenGL
65 import OpenGL.GL
66 from OpenGL.GL import *
67 import OpenGL.GLU
68 from OpenGL.GLU import *
70 import StringIO
72 def getBroadcast(ip):
73 global BROADCAST
74 BROADCAST = ip
76 print "getBroadcast(): Broadcast is reported to be", ip
77 return
79 reactor.resolve('<broadcast>').addCallback(getBroadcast)
81 the_event_receiver = 0
83 global the_engine
84 global the_client
86 class QueueLock:
87 def __init__(self):
89 self.items = []
90 self.items_lock = Lock()
92 def size(self):
94 return len(self.items)
96 def getItem(self):
98 self.items_lock.acquire()
99 the_item = self.items.pop(0)
100 self.items_lock.release()
102 return the_item
104 def addItem(self, new_item):
106 self.items_lock.acquire()
107 self.items.append(new_item)
108 self.items_lock.release()
110 return
112 class EventReceiver(QueueLock):
114 def getEvent(self):
115 return self.getItem()
116 def addEvent(self, event):
117 self.addItem(event)
118 return
120 class CommandLine(QueueLock):
122 def getCommand(self):
123 return self.getItem()
124 def addCommand(self, command):
125 self.addItem(command)
126 return
128 class Multicast(DatagramProtocol):
130 def startProtocol(self):
131 self.transport.joinGroup(MULTICAST)
133 def datagramReceived(self, datagram, address):
135 pass
137 class Client(DatagramProtocol):
139 def datagramReceived(self, data, (host, port)):
141 if data[:len(YOUTHERE)] == YOUTHERE:
143 # print "Client.datagramReceived(): Recieved YOUTHERE, responding with IMHERE"
144 self.transport.write(IMHERE, (host, port))
146 if data[:len(SERVEROFFER)] == SERVEROFFER:
148 split_strings = data.split()
150 self.servers[split_strings[2]] = (host, int(split_strings[1]))
152 event = [SERVEROFFER, {'server_name': split_strings[2],
153 'server_address': self.servers[split_strings[2]]}]
154 the_engine.events.addEvent(event)
156 print "Client.datagramReceived(): Received SERVEROFFER"
158 if data[:len(YOUREIN)] == YOUREIN:
160 if (host, port) == self.requested_server:
161 self.current_server = (host, port)
162 self.requested_server = ()
164 event = [YOUREIN]
165 data = {'server': self.current_server}
166 event.append(data)
168 the_engine.events.addEvent(event)
170 print "Client.datagramReceived(): Received YOUREIN, joined server"
172 return
174 if data[:len(LIST)] == LIST:
176 print "Client.datagramReceived(): Received LIST"
178 split_strings = data.split()
180 self.members = []
182 for string in split_strings:
183 if string != LIST:
184 self.members.append(string)
186 event = [LIST]
187 data = {'names': self.members, 'server_address': (host, port)}
188 event.append(data)
190 the_engine.events.addEvent(event)
192 return
194 if data[:len(SOMEONEJOINED)] == SOMEONEJOINED:
196 if (host, port) == self.current_server:
198 print "Client.datagramReceived(): Received SOMEONEJOINED"
200 left_member = ''
202 for member in self.members:
203 if member == data[len(SOMEONEJOINED) + 1:]:
204 left_member = member
206 if left_member == '':
207 self.members.append(left_member)
209 event = [SOMEONEJOINED]
210 data = {'name': data[len(SOMEONEJOINED) + 1:]}
212 event.append(data)
214 the_engine.events.addEvent(event)
216 return
218 if data[:len(SOMEONELEFT)] == SOMEONELEFT:
220 if (host, port) == self.current_server:
222 name = data[len(SOMEONELEFT) + 1:]
224 print "debug", name, self.members
226 if name in self.members:
227 print "Client.datagramReceived(): Received SOMEONELEFT"
229 self.members.remove(name)
231 event = [SOMEONELEFT]
232 data = {'name': name}
234 event.append(data)
236 the_engine.events.addEvent(event)
238 else:
239 print "Client.datagramReceived(): Received SOMEONELEFT, but", name, "not present in roster"
241 return
242 if data[:len(YOUROUT)] == YOUROUT:
244 if (host, port) == self.current_server:
246 print "Client.datagramReceived(): Recieved YOUROUT"
248 self.current_server = ()
250 event = [YOUROUT]
251 data = {}
252 event.append(data)
254 the_engine.events.addEvent(event)
256 return
258 if data[:len(LETTER)] == LETTER:
260 if (host, port) == self.current_server:
261 print "Client.datagramReceived(): Received LETTER"
263 split_strings = data.split(':')
265 message = data[data.find(':', len(LETTER) + 1) + 1:]
266 message_origin = split_strings[1]
268 event = [LETTER]
269 data = {'message': message, 'origin': message_origin}
270 event.append(data)
272 the_engine.events.addEvent(event)
274 return
276 def init(self, params):
278 self.params = params
280 self.current_server = ()
281 self.requested_server = ()
282 self.servers = {}
284 self.inited = 1
286 return
288 def executeCommand(self, command, data):
290 reactor.callFromThread(self.executeThreadCommand, command, data)
292 return
294 def executeThreadCommand(self, command, data):
296 if command == SERVERKILL:
298 if self.current_server != ():
300 message = ''.join([SERVERKILL, ' '])
302 if data.has_key('password'):
303 message = ''.join([message, data['password']])
305 self.transport.write(message, self.current_server)
307 if command == SERVERREQUEST:
309 message = ''.join([SERVERREQUEST, ' ', str(self.params['message_port'])])
311 the_multicast.transport.write(message, (MULTICAST, self.params['broadcast_port']))
312 # self.transport.write(message, ('255.255.255.255', self.params['broadcast_port']))
314 if command == GETLIST:
316 message = GETLIST
318 if data.has_key('server'):
320 if self.servers.has_key(data['server']):
321 self.transport.write(message, self.servers[data['server']])
323 else:
325 if self.current_server != ():
326 self.transport.write(message, self.current_server)
328 if command == IMOUT:
330 if self.current_server != ():
332 message = IMOUT
334 self.transport.write(message, self.current_server)
336 self.current_server = ()
338 if command == LETTER:
340 if self.current_server != ():
342 message = ''.join([LETTER, ':'])
344 for dest in data['destinations']:
345 if dest in self.members:
346 message = ''.join([message, ' ' , dest])
348 message = ''.join([message, ':', data['message']])
350 self.transport.write(message, self.current_server)
352 if command == WANTIN:
354 if data.has_key('server'):
355 if self.servers.has_key(data['server']):
357 self.transport.write(''.join([WANTIN, ' ', self.params['name']]),
358 self.servers[data['server']])
359 self.current_server = ()
360 self.requested_server = self.servers[data['server']]
362 return
364 class Engine:
366 def __init__(self, config):
368 self.config = config
369 self.running = 1
371 global the_engine
372 the_engine = self
374 video_flags = OPENGL|DOUBLEBUF
376 pygame.init()
377 self.display = pygame.display.set_mode(config['window_size'], video_flags)
379 self.font = pygame.font.SysFont("default", 18)
380 self.fontBig = pygame.font.SysFont("default", 24)
381 self.fontSub = pygame.font.SysFont("default", 20)
382 self.theme = pgui.Theme(['test_theme', 'gray', 'default'])
383 # self.theme = pgui.Theme('gray')
384 # self.theme = pgui.Theme('default')
386 self.resize((config['window_size']))
388 glShadeModel(GL_SMOOTH)
389 glClearColor(self.config['background_color'][0],
390 self.config['background_color'][1],
391 self.config['background_color'][2],
392 self.config['background_color'][3])
393 glClearDepth(1.0)
394 glEnable(GL_DEPTH_TEST)
395 glDepthFunc(GL_LEQUAL)
396 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
398 pygame.display.set_caption(config['window_title'])
400 self.gui_screen = lamina.LaminaScreenSurface()
402 self.app = pgui.App(theme=self.theme)
403 self.app._screen = self.gui_screen.surf
404 self.main_container = pgui.Container(width=config['window_size'][0])
406 self.files = {}
408 self.events = EventReceiver()
410 # self.files is a map of filename to file
412 # The file has this:
413 # {parent, [children], {object_defs},
414 # {menu_defs}, {object_instances}, {menu_instances}}
416 self.zipfiles = []
418 for file in listdir(self.config['pack_dir']):
419 if (is_zipfile(os.path.join(self.config['pack_dir'], file))):
420 self.zipfiles.append(ZipFile(os.path.join(self.config['pack_dir'], file)))
422 self.running = self.addFile(self.config['init'], '')
423 self.app.init(self.main_container)
425 self.ticks = pygame.time.get_ticks()
426 self.frames = 0
428 if self.running == 0:
429 print "Engine.__init__(): Failed adding initial file"
431 def run(self):
433 global the_client
435 while self.running:
437 self.process_events()
439 self.draw()
441 pygame.display.flip()
443 return
445 def updateFPS(self):
447 self.oldticks = self.ticks
448 self.ticks = pygame.time.get_ticks()
450 self.frames += 1
452 self.fps = (self.frames * 1000) / (self.ticks - self.oldticks) / 1000
454 pygame.display.set_caption(''.join([self.config['window_title'], ' ', str(self.fps)]))
456 return
458 def process_events(self):
460 change = 0
462 for e in pygame.event.get():
463 if e.type == QUIT:
464 self.running = 0
465 print "Should be quitting..."
467 self.killGame()
469 self.app.event((e))
470 change = self.app.update(self.gui_screen.surf)
472 if (change != 0):
473 self.gui_screen.refresh(change)
475 new_event = self.convertEvent(e)
476 self.events.addEvent(new_event)
478 iterating = 1
479 while iterating:
481 if self.events.size():
482 new_event = self.events.getEvent()
483 else:
484 iterating = 0
486 if not iterating:
487 return
489 if iterating:
490 for file in self.files.keys():
492 for name in self.files[file]['object_instances'].keys():
494 self.files[file]['object_instances'][name].event(new_event[0], new_event[1])
496 return
498 def convertEvent(self, e):
500 data = {}
502 if e.type == QUIT:
503 data['none'] = ''
505 if e.type == ACTIVEEVENT:
506 data['gain'] = e.gain
507 data['state'] = e.state
509 if e.type == KEYDOWN:
510 data['unicode'] = e.unicode
511 data['key'] = e.key
512 data['mod'] = e.mod
514 if e.type == KEYUP:
515 data['key'] = e.key
516 data['mod'] = e.mod
518 if e.type == MOUSEMOTION:
519 data['pos'] = e.pos
520 data['rel'] = e.rel
521 data['buttons'] = e.buttons
523 if e.type == MOUSEBUTTONUP:
524 data['pos'] = e.pos
525 data['button'] = e.button
527 if e.type == MOUSEBUTTONDOWN:
528 data['pos'] = e.pos
529 data['button'] = e.button
531 if e.type == JOYAXISMOTION:
532 data['joy'] = e.joy
533 data['axis'] = e.axis
534 data['value'] = e.value
536 if e.type == JOYBALLMOTION:
537 data['joy'] = e.joy
538 data['ball'] = e.ball
539 data['rel'] = e.rel
541 if e.type == JOYHATMOTION:
542 data['joy'] = e.joy
543 data['hat'] = e.hat
544 data['value'] = e.value
546 if e.type == JOYBUTTONUP:
547 data['joy'] = e.joy
548 data['button'] = e.button
550 if e.type == JOYBUTTONDOWN:
551 data['joy'] = e.joy
552 data['button'] = e.button
554 if e.type == VIDEORESIZE:
555 data['size'] = e.size
556 data['w'] = e.w
557 data['h'] = e.h
559 if e.type == VIDEOEXPOSE:
560 data['none'] = ''
562 if e.type == USEREVENT:
563 data['code'] = e.code
565 type = ''
567 if e.type == QUIT: type = "QUIT"
568 if e.type == ACTIVEEVENT: type = "ACTIVEEVENT"
569 if e.type == KEYDOWN: type = "KEYDOWN"
570 if e.type == KEYUP: type = "KEYUP"
571 if e.type == MOUSEMOTION : type = "MOUSEMOTION"
572 if e.type == MOUSEBUTTONUP: type = "MOUSEBUTTONUP"
573 if e.type == MOUSEBUTTONDOWN: type = "MOUSEBUTTONDOWN"
574 if e.type == JOYAXISMOTION: type = "JOYAXISMOTION"
575 if e.type == JOYBALLMOTION: type = "JOYBALLMOTION"
576 if e.type == JOYHATMOTION: type = "JOYHATMOTION"
577 if e.type == JOYBUTTONUP: type = "JOYBUTTONUP"
578 if e.type == JOYBUTTONDOWN: type = "JOYBUTTONDOWN"
579 if e.type == VIDEORESIZE: type = "VIDEORESIZE"
580 if e.type == VIDEOEXPOSE: type = "VIDEOEXPOSE"
581 if e.type == USEREVENT: type = "USEREVENT"
583 return [type, data]
585 def draw(self):
587 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
588 glLoadIdentity()
590 # draw stuff
592 glLoadIdentity()
593 self.gui_screen.display()
595 def resize(self, (width, height)):
596 if height==0:
597 height=1
598 glViewport(0, 0, width, height)
599 glMatrixMode(GL_PROJECTION)
600 glLoadIdentity()
601 gluPerspective(45, 1.0*width/height, 0.1, 100.0)
602 glMatrixMode(GL_MODELVIEW)
603 glLoadIdentity()
605 return
607 def addFile(self, filename, parent):
609 # Because I have alot of nesting in this function,
610 # I am using 2 space formatting
612 for zipfile in self.zipfiles:
614 for file in zipfile.namelist():
616 if (file == filename):
617 dom = parseString(zipfile.read(file))
619 object_instances_d = []
620 menu_instances = []
622 if dom.childNodes[0].nodeName == 'game':
623 self.files[filename] = {
624 'object_defs': {},
625 'children': [],
626 'parent': '',
627 'object_instances': {},
628 'menu_instances': {},
629 'menu_defs': {}}
631 for node in dom.childNodes[0].childNodes:
633 if (node.nodeName == 'def'):
635 for sub_node in node.childNodes:
637 if (sub_node.nodeName == 'object'):
639 temp_object_def = {}
641 for suber_node in sub_node.childNodes:
643 if (suber_node.nodeName == 'name'):
644 if len(suber_node.childNodes):
645 temp_object_def['name'] = suber_node.childNodes[0].nodeValue
647 if (suber_node.nodeName == 'script'):
648 if len(suber_node.childNodes):
649 temp_object_def['script'] = suber_node.childNodes[0].nodeValue
651 if (suber_node.nodeName == 'tangible'):
652 if len(suber_node.childNodes):
653 temp_object_def['tangible'] = suber_node.childNodes[0].nodeValue
655 if (suber_node.nodeName == 'type'):
656 if len(suber_node.childNodes):
657 temp_object_def['type'] = suber_node.childNodes[0].nodeValue
659 self.files[filename]['object_defs'][temp_object_def['name']] = temp_object_def
660 temp_object_def = {}
662 if (sub_node.nodeName == 'menu'):
664 temp_menu_def = {}
665 temp_menu_def['elements'] = {}
667 temp_element_set = {}
669 for suber_node in sub_node.childNodes:
671 if (suber_node.nodeName == 'name'):
672 temp_menu_def['name'] = suber_node.childNodes[0].nodeValue
674 if (suber_node.nodeName == 'elements'):
676 for suberer_node in suber_node.childNodes:
678 if (suberer_node.nodeType != 3 and suberer_node.nodeType != 8):
679 if (suberer_node.hasAttribute('name')):
680 temp_element_set['name'] = suberer_node.getAttribute('name')
682 if (suberer_node.hasAttribute('x')):
683 temp_element_set['x'] = int(suberer_node.getAttribute('x'))
685 if (suberer_node.hasAttribute('y')):
686 temp_element_set['y'] = int(suberer_node.getAttribute('y'))
688 if (suberer_node.hasAttribute('width')):
689 temp_element_set['width'] = int(suberer_node.getAttribute('width'))
691 if (suberer_node.hasAttribute('height')):
692 temp_element_set['height'] = int(suberer_node.getAttribute('height'))
694 if (suberer_node.hasAttribute('parent')):
695 temp_element_set['parent'] = suberer_node.getAttribute('parent')
697 if (suberer_node.hasAttribute('target')):
698 temp_element_set['target'] = suberer_node.getAttribute('target')
700 if (suberer_node.hasAttribute('text')):
701 temp_element_set['text'] = suberer_node.getAttribute('text')
703 temp_element_set['type'] = suberer_node.nodeName
704 temp_menu_def['elements'][temp_element_set['name']] = temp_element_set
705 temp_element_set = {}
707 self.files[filename]['menu_defs'][temp_menu_def['name']] = temp_menu_def
709 temp_menu_def = {}
710 temp_element_set = {}
712 if (node.nodeName == 'instance'):
714 for sub_node in node.childNodes:
716 if (sub_node.nodeName == 'object'):
717 object_instances_d.append(sub_node.childNodes[0].nodeValue)
719 if (sub_node.nodeName == 'menu'):
720 menu_instances.append(sub_node.childNodes[0].nodeValue)
722 if (parent != ''):
723 self.files[parent]['children'].append(filename)
724 self.files[filename]['parent'] = parent
726 # create instances
728 for menuname, menu_data in self.files[filename]['menu_defs'].iteritems():
729 self.files[filename]['menu_instances'][menuname] = Menu(menu_def=menu_data)
731 for menuname in menu_instances:
732 if (self.files[filename]['menu_instances'].has_key(menuname)):
733 self.files[filename]['menu_instances'][menuname].show()
735 for file in self.files.keys():
736 if self.files[file]['menu_instances'].has_key(menuname):
737 self.files[file]['menu_instances'][menuname].show()
739 for objectname in object_instances_d:
740 self.addObject(objectname)
742 return 1
743 return 0
744 # ending 2-space formatting
746 def removeFile(self, filename):
748 if (self.files.has_key(filename)):
750 for child in self.files[filename]['children']:
751 self.removeFile(child)
753 del self.files[filename]['children']
755 parent = self.files[filename]['parent']
756 self.files[parent].pop(self.files[parent]['children'].index(filename))
758 del self.files[filename]
760 return
762 def getVisibleMenus(self):
764 menus = {}
766 for file, contents in self.files.iteritems():
767 for name, menu in contents['menu_instances'].iteritems():
768 if not menu.hidden:
769 menus[name] = menu
771 return menus
773 def hideAllMenus(self):
775 for file, contents in self.files.iteritems():
776 for name, menu in contents['menu_instances'].iteritems():
777 menu.hide()
779 return
781 def showMenu(self, menu_name):
783 for file, contents in self.files.iteritems():
784 for name, menu in contents['menu_instances'].iteritems():
785 if contents['menu_instances'].has_key(menu_name):
786 contents['menu_instances'][menu_name].show()
788 return
790 def hideMenu(self, menu_name):
792 for file, contents in self.files:
793 for name, menu in contents['menu_instances'].iteritems():
794 if contents['menu_instances'].has_key(menu_name):
795 contents['menu_instances'][menu_name].hide()
797 return
799 def setMenu(self, menu_name):
801 self.hideAllMenus()
802 self.showMenu(menu_name)
804 return
806 def addObject(self, objectname):
808 for file in self.files.keys():
809 if self.files[file]['object_defs'].has_key(objectname):
810 self.files[file]['object_instances'][objectname] = GameObject(
811 self.files[file]['object_defs'][objectname])
813 return
815 def removeObject(self, objectname):
817 for file in self.files.keys():
818 if self.files[file]['object_defs'].has_key(objectname):
819 del self.files[file]['object_instances'][objectname]
821 return
823 def addListItem(self, menuname, item, data, dvalue):
825 for file in self.files:
826 if self.files[file]['menu_instances'].has_key(menuname):
827 if self.files[file]['menu_instances'][menuname].widgets.has_key(item):
828 the_widget = self.files[file]['menu_instances'][menuname].widgets[item]
830 the_widget.add(data, value=dvalue)
831 the_widget.resize()
832 the_widget.repaint()
834 return
836 def clearListItem(self, menuname, item):
838 for file in self.files:
839 if self.files[file]['menu_instances'].has_key(menuname):
840 if self.files[file]['menu_instances'][menuname].widgets.has_key(item):
841 the_widget = self.files[file]['menu_instances'][menuname].widgets[item]
843 the_widget.clear()
844 the_widget.resize()
845 the_widget.repaint()
847 return
849 def removeListItem(self, menuname, item, value):
851 for file in self.files:
852 if self.files[file]['menu_instances'].has_key(menuname):
853 if self.files[file]['menu_instances'][menuname].has_key(item):
854 the_widget = self.files[file]['menu_instances'][menuname][item]
856 the_widget.remove(value)
857 the_widget.resize()
858 the_widget.repaint()
860 return
862 def getListValue(self, menuname, item):
864 for file in self.files:
865 if self.files[file]['menu_instances'].has_key(menuname):
867 if self.files[file]['menu_instances'][menuname].widgets.has_key(item):
868 the_widget = self.files[file]['menu_instances'][menuname].widgets[item]
870 return the_widget.value
872 return ''
874 def getImage(self, filename):
876 the_buf = pygame.image.load(self.getStringIOFile(filename))
878 return the_buf
880 def getStringIOFile(self, filename):
882 for zip_file in self.zipfiles:
883 for file in zip_file.namelist():
885 if (filename == file):
887 the_string_io = StringIO.StringIO()
888 print >>the_string_io, zip_file.read(file)
889 the_string_io.seek(0)
891 return the_string_io
892 return ''
894 def getStringData(self, filename):
895 for zip_file in self.zipfiles:
896 for file in zip_file.namelist():
898 if (filename == file):
899 return zip_file.read(file)
900 return ''
902 def killThreadGame(self):
904 reactor.stop()
906 return
908 def killGame(self):
910 reactor.callFromThread(self.killThreadGame)
912 return
914 class Menu:
916 def __init__(self, menu_def):
918 self.menu_def = menu_def
919 self.widgets = {}
921 for name, element in menu_def['elements'].iteritems():
923 multiplier_x = float(the_engine.config['window_size'][0]) / 100.00
924 multiplier_y = float(the_engine.config['window_size'][1]) / 100.00
926 dx = float(element['x']) * multiplier_x
927 dy = float(element['y']) * multiplier_y
929 dwidth = float(element['width']) * multiplier_x
930 dheight = float(element['height']) * multiplier_y
932 if (element['type'] == 'button'):
933 self.widgets[name] = pgui.Button(element['text'].encode(), width=dwidth, height=dheight)
934 self.widgets[name].connect(pgui.CLICK, self.clicked, name)
936 if (element['type'] == 'image'):
937 self.widgets[name] = pgui.Image(the_engine.getImage(element['text']))
939 if (element['type'] == 'label'):
940 self.widgets[name] = pgui.Label(element['text'])
942 if (element['type'] == 'listbox'):
943 self.widgets[name] = pgui.List(width=dwidth, height=dheight)
944 self.widgets[name].connect(pgui.CLICK, self.clicked, name)
946 if (self.widgets.has_key(name)):
947 self.widgets[name].resize(width=dwidth, height=dheight)
948 else:
949 print "Menu.__init__(): Widget type", element['type'], " not implemented yet, skipping."
951 self.hidden = 1
953 def show(self):
955 global the_engine
957 multiplier_x = float(the_engine.config['window_size'][0]) / 100.00
958 multiplier_y = float(the_engine.config['window_size'][1]) / 100.00
960 if (self.hidden == 1):
961 for name, element in self.menu_def['elements'].iteritems():
962 dx = float(element['x']) * multiplier_x
963 dy = float(element['y']) * multiplier_y
965 if self.widgets.has_key(name):
966 the_engine.main_container.add(self.widgets[name], dx, dy)
968 self.hidden = 0
970 return
972 def hide(self):
974 global the_engine
976 if (self.hidden != 1):
977 for name, element in self.menu_def['elements'].iteritems():
979 if (self.widgets.has_key(name)):
980 the_engine.main_container.remove(self.widgets[name])
982 self.hidden = 1
984 return
986 def clicked(self, widget):
988 if self.menu_def['elements'].has_key(widget):
990 if self.menu_def['elements'][widget]['target'] != '':
991 exec(self.menu_def['elements'][widget]['target'])
993 the_engine.events.addEvent(['WIDGET_CLICKED',
994 {'name': widget, 'menu_name': self.menu_def['name']}])
996 return
998 class GameObject:
1000 def __init__(self, dmold):
1002 self.mold = dmold
1003 global the_functions
1004 global in_script
1006 if self.mold['script'] != '':
1008 in_script = 1
1010 the_file = the_engine.getStringData(self.mold['script'])
1011 if the_file != '':
1012 exec(the_file)
1014 in_script = 0
1015 self.my_functions = the_functions
1017 the_functions = {}
1019 def event(self, event, data):
1021 if self.my_functions.has_key(event):
1023 self.my_functions[event](data)
1025 return
1027 def main():
1028 # parse command line stuff
1030 if (len(sys.argv) > 1):
1031 config = sys.argv[1]
1032 else:
1033 print "main(): No config specified, using", CONFIG
1034 config = CONFIG
1036 configuration = parse_config(config)
1038 if (configuration.has_key('error') and configuration['error']):
1039 print "main(): Error in parsing config."
1041 the_event_receiver = EventReceiver()
1043 global client_params
1044 client_params = {'broadcast_port':configuration['broadcast_port'],
1045 'broadcast_bind':configuration['broadcast_bind'],
1046 'message_port':configuration['message_port'],
1047 'name':configuration['name']}
1049 global the_engine
1050 global the_client
1052 the_engine = Engine(configuration)
1054 the_client = Client()
1055 the_client_thread = threading.Thread(target=run_net)
1057 the_client.init(client_params)
1059 the_client_thread.start()
1060 the_engine.run()
1062 the_engine.killGame()
1064 sys.exit()
1066 the_client_thread.join()
1068 return
1070 def run_net():
1072 global client_params
1073 global the_multicast
1075 the_multicast = Multicast()
1076 config = client_params
1078 reactor.listenMulticast(config['broadcast_bind'], the_multicast)
1079 reactor.listenUDP(config['message_port'], the_client)
1081 reactor.run(installSignalHandlers=0)
1083 return
1085 def parse_config(filename):
1086 results = {'error': 1}
1088 if (exists(filename)):
1089 dom = parse(filename)
1090 else:
1091 print "parse_config():", filename, "doesn't exist."
1092 return results
1094 if (dom.childNodes[0].nodeName == 'config'):
1095 for node in dom.childNodes[0].childNodes:
1097 if (node.nodeName == 'window_title'):
1098 results['window_title'] = node.childNodes[0].nodeValue
1100 if (node.nodeName == 'log'):
1101 results['log'] = node.childNodes[0].nodeValue
1103 if (node.nodeName == 'name'):
1104 results['name'] = node.childNodes[0].nodeValue
1106 if (node.nodeName == 'font'):
1107 results['font'] = node.childNodes[0].nodeValue
1109 if (node.nodeName == 'init'):
1110 results['init'] = node.childNodes[0].nodeValue
1112 if (node.nodeName == 'message_port'):
1113 results['message_port'] = int(node.childNodes[0].nodeValue)
1115 if (node.nodeName == 'broadcast_port'):
1116 results['broadcast_port'] = int(node.childNodes[0].nodeValue)
1118 if (node.nodeName == 'broadcast_bind'):
1119 results['broadcast_bind'] = int(node.childNodes[0].nodeValue)
1121 if (node.nodeName == 'fullscreen'):
1122 results['fullscreen'] = int(node.childNodes[0].nodeValue)
1124 if (node.nodeName == 'background_color'):
1126 string_parts = node.childNodes[0].nodeValue.split()
1127 results['background_color'] = [float(string_parts[0]), float(string_parts[1])]
1128 results['background_color'].append(float(string_parts[2]))
1129 results['background_color'].append(float(string_parts[3]))
1131 if (node.nodeName == 'window_size'):
1133 string_parts = node.childNodes[0].nodeValue.split()
1134 results['window_size'] = ((int(string_parts[0]), int(string_parts[1])))
1136 if (node.nodeName == 'gravity'):
1138 string_parts = node.childNodes[0].nodeValue.split()
1139 results['gravity'] = [float(string_parts[0]), float(string_parts[1])]
1140 results['gravity'].append(float(string_parts[2]))
1142 if (node.nodeName == 'step_size'):
1143 results['step_size'] = float(node.childNodes[0].nodeValue)
1145 if (node.nodeName == 'pack_dir'):
1146 results['pack_dir'] = node.childNodes[0].nodeValue
1148 results['error'] = 0
1150 return results
1152 if __name__ == '__main__':
1153 main()