Fixed some network stuff.
[krufty_fps.git] / more_twisted.py
blob6261fbc8e66ecc52d0d691955402b81e1fbdddd7
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(data[len(SOMEONEJOINED) + 1:])
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):
289 if command == SERVERKILL:
291 if self.current_server != ():
293 message = ''.join([SERVERKILL, ' '])
295 if data.has_key('password'):
296 message = ''.join([message, data['password']])
298 self.transport.write(message, self.current_server)
300 if command == SERVERREQUEST:
302 message = ''.join([SERVERREQUEST, ' ', str(self.params['message_port'])])
304 the_multicast.transport.write(message, (MULTICAST, self.params['broadcast_port']))
305 # self.transport.write(message, ('255.255.255.255', self.params['broadcast_port']))
307 if command == GETLIST:
309 message = GETLIST
311 if data.has_key('server'):
313 if self.servers.has_key(data['server']):
314 self.transport.write(message, self.servers[data['server']])
316 else:
318 if self.current_server != ():
319 self.transport.write(message, self.current_server)
321 if command == IMOUT:
323 if self.current_server != ():
325 message = IMOUT
327 self.transport.write(message, self.current_server)
329 self.current_server = ()
331 if command == LETTER:
333 if self.current_server != ():
335 message = ''.join([LETTER, ':'])
337 for dest in data['destinations']:
338 if dest in self.members:
339 message = ''.join([message, ' ' , dest])
341 message = ''.join([message, ':', data['message']])
343 self.transport.write(message, self.current_server)
345 if command == WANTIN:
347 if data.has_key('server'):
348 if self.servers.has_key(data['server']):
350 self.transport.write(''.join([WANTIN, ' ', self.params['name']]),
351 self.servers[data['server']])
352 self.current_server = ()
353 self.requested_server = self.servers[data['server']]
355 return
357 class Engine:
359 def __init__(self, config):
361 self.config = config
362 self.running = 1
364 global the_engine
365 the_engine = self
367 video_flags = OPENGL|DOUBLEBUF
369 pygame.init()
370 self.display = pygame.display.set_mode(config['window_size'], video_flags)
372 self.font = pygame.font.SysFont("default", 18)
373 self.fontBig = pygame.font.SysFont("default", 24)
374 self.fontSub = pygame.font.SysFont("default", 20)
375 self.theme = pgui.Theme(['test_theme', 'gray', 'default'])
376 # self.theme = pgui.Theme('gray')
377 # self.theme = pgui.Theme('default')
379 self.resize((config['window_size']))
381 glShadeModel(GL_SMOOTH)
382 glClearColor(self.config['background_color'][0],
383 self.config['background_color'][1],
384 self.config['background_color'][2],
385 self.config['background_color'][3])
386 glClearDepth(1.0)
387 glEnable(GL_DEPTH_TEST)
388 glDepthFunc(GL_LEQUAL)
389 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
391 pygame.display.set_caption(config['window_title'])
393 self.gui_screen = lamina.LaminaScreenSurface()
395 self.app = pgui.App(theme=self.theme)
396 self.app._screen = self.gui_screen.surf
397 self.main_container = pgui.Container(width=config['window_size'][0])
399 self.files = {}
401 self.events = EventReceiver()
403 # self.files is a map of filename to file
405 # The file has this:
406 # {parent, [children], {object_defs},
407 # {menu_defs}, {object_instances}, {menu_instances}}
409 self.zipfiles = []
411 for file in listdir(self.config['pack_dir']):
412 if (is_zipfile(os.path.join(self.config['pack_dir'], file))):
413 self.zipfiles.append(ZipFile(os.path.join(self.config['pack_dir'], file)))
415 self.running = self.addFile(self.config['init'], '')
416 self.app.init(self.main_container)
418 self.ticks = pygame.time.get_ticks()
419 self.frames = 0
421 if self.running == 0:
422 print "Engine.__init__(): Failed adding initial file"
424 def run(self):
426 global the_client
428 while self.running:
430 self.process_events()
432 self.draw()
434 pygame.display.flip()
436 return
438 def updateFPS(self):
440 self.oldticks = self.ticks
441 self.ticks = pygame.time.get_ticks()
443 self.frames += 1
445 self.fps = (self.frames * 1000) / (self.ticks - self.oldticks) / 1000
447 pygame.display.set_caption(''.join([self.config['window_title'], ' ', str(self.fps)]))
449 return
451 def process_events(self):
453 change = 0
455 for e in pygame.event.get():
456 if e.type == QUIT:
457 self.running = 0
458 print "Should be quitting..."
460 self.killGame()
462 self.app.event((e))
463 change = self.app.update(self.gui_screen.surf)
465 if (change != 0):
466 self.gui_screen.refresh(change)
468 new_event = self.convertEvent(e)
469 self.events.addEvent(new_event)
471 iterating = 1
472 while iterating:
474 if self.events.size():
475 new_event = self.events.getEvent()
476 else:
477 iterating = 0
479 if not iterating:
480 return
482 if iterating:
483 for file in self.files.keys():
485 for name in self.files[file]['object_instances'].keys():
487 self.files[file]['object_instances'][name].event(new_event[0], new_event[1])
489 return
491 def convertEvent(self, e):
493 data = {}
495 if e.type == QUIT:
496 data['none'] = ''
498 if e.type == ACTIVEEVENT:
499 data['gain'] = e.gain
500 data['state'] = e.state
502 if e.type == KEYDOWN:
503 data['unicode'] = e.unicode
504 data['key'] = e.key
505 data['mod'] = e.mod
507 if e.type == KEYUP:
508 data['key'] = e.key
509 data['mod'] = e.mod
511 if e.type == MOUSEMOTION:
512 data['pos'] = e.pos
513 data['rel'] = e.rel
514 data['buttons'] = e.buttons
516 if e.type == MOUSEBUTTONUP:
517 data['pos'] = e.pos
518 data['button'] = e.button
520 if e.type == MOUSEBUTTONDOWN:
521 data['pos'] = e.pos
522 data['button'] = e.button
524 if e.type == JOYAXISMOTION:
525 data['joy'] = e.joy
526 data['axis'] = e.axis
527 data['value'] = e.value
529 if e.type == JOYBALLMOTION:
530 data['joy'] = e.joy
531 data['ball'] = e.ball
532 data['rel'] = e.rel
534 if e.type == JOYHATMOTION:
535 data['joy'] = e.joy
536 data['hat'] = e.hat
537 data['value'] = e.value
539 if e.type == JOYBUTTONUP:
540 data['joy'] = e.joy
541 data['button'] = e.button
543 if e.type == JOYBUTTONDOWN:
544 data['joy'] = e.joy
545 data['button'] = e.button
547 if e.type == VIDEORESIZE:
548 data['size'] = e.size
549 data['w'] = e.w
550 data['h'] = e.h
552 if e.type == VIDEOEXPOSE:
553 data['none'] = ''
555 if e.type == USEREVENT:
556 data['code'] = e.code
558 type = ''
560 if e.type == QUIT: type = "QUIT"
561 if e.type == ACTIVEEVENT: type = "ACTIVEEVENT"
562 if e.type == KEYDOWN: type = "KEYDOWN"
563 if e.type == KEYUP: type = "KEYUP"
564 if e.type == MOUSEMOTION : type = "MOUSEMOTION"
565 if e.type == MOUSEBUTTONUP: type = "MOUSEBUTTONUP"
566 if e.type == MOUSEBUTTONDOWN: type = "MOUSEBUTTONDOWN"
567 if e.type == JOYAXISMOTION: type = "JOYAXISMOTION"
568 if e.type == JOYBALLMOTION: type = "JOYBALLMOTION"
569 if e.type == JOYHATMOTION: type = "JOYHATMOTION"
570 if e.type == JOYBUTTONUP: type = "JOYBUTTONUP"
571 if e.type == JOYBUTTONDOWN: type = "JOYBUTTONDOWN"
572 if e.type == VIDEORESIZE: type = "VIDEORESIZE"
573 if e.type == VIDEOEXPOSE: type = "VIDEOEXPOSE"
574 if e.type == USEREVENT: type = "USEREVENT"
576 return [type, data]
578 def draw(self):
580 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
581 glLoadIdentity()
583 # draw stuff
585 glLoadIdentity()
586 self.gui_screen.display()
588 def resize(self, (width, height)):
589 if height==0:
590 height=1
591 glViewport(0, 0, width, height)
592 glMatrixMode(GL_PROJECTION)
593 glLoadIdentity()
594 gluPerspective(45, 1.0*width/height, 0.1, 100.0)
595 glMatrixMode(GL_MODELVIEW)
596 glLoadIdentity()
598 return
600 def addFile(self, filename, parent):
602 # Because I have alot of nesting in this function,
603 # I am using 2 space formatting
605 for zipfile in self.zipfiles:
607 for file in zipfile.namelist():
609 if (file == filename):
610 dom = parseString(zipfile.read(file))
612 object_instances_d = []
613 menu_instances = []
615 if dom.childNodes[0].nodeName == 'game':
616 self.files[filename] = {
617 'object_defs': {},
618 'children': [],
619 'parent': '',
620 'object_instances': {},
621 'menu_instances': {},
622 'menu_defs': {}}
624 for node in dom.childNodes[0].childNodes:
626 if (node.nodeName == 'def'):
628 for sub_node in node.childNodes:
630 if (sub_node.nodeName == 'object'):
632 temp_object_def = {}
634 for suber_node in sub_node.childNodes:
636 if (suber_node.nodeName == 'name'):
637 if len(suber_node.childNodes):
638 temp_object_def['name'] = suber_node.childNodes[0].nodeValue
640 if (suber_node.nodeName == 'script'):
641 if len(suber_node.childNodes):
642 temp_object_def['script'] = suber_node.childNodes[0].nodeValue
644 if (suber_node.nodeName == 'tangible'):
645 if len(suber_node.childNodes):
646 temp_object_def['tangible'] = suber_node.childNodes[0].nodeValue
648 if (suber_node.nodeName == 'type'):
649 if len(suber_node.childNodes):
650 temp_object_def['type'] = suber_node.childNodes[0].nodeValue
652 self.files[filename]['object_defs'][temp_object_def['name']] = temp_object_def
653 temp_object_def = {}
655 if (sub_node.nodeName == 'menu'):
657 temp_menu_def = {}
658 temp_menu_def['elements'] = {}
660 temp_element_set = {}
662 for suber_node in sub_node.childNodes:
664 if (suber_node.nodeName == 'name'):
665 temp_menu_def['name'] = suber_node.childNodes[0].nodeValue
667 if (suber_node.nodeName == 'elements'):
669 for suberer_node in suber_node.childNodes:
671 if (suberer_node.nodeType != 3 and suberer_node.nodeType != 8):
672 if (suberer_node.hasAttribute('name')):
673 temp_element_set['name'] = suberer_node.getAttribute('name')
675 if (suberer_node.hasAttribute('x')):
676 temp_element_set['x'] = int(suberer_node.getAttribute('x'))
678 if (suberer_node.hasAttribute('y')):
679 temp_element_set['y'] = int(suberer_node.getAttribute('y'))
681 if (suberer_node.hasAttribute('width')):
682 temp_element_set['width'] = int(suberer_node.getAttribute('width'))
684 if (suberer_node.hasAttribute('height')):
685 temp_element_set['height'] = int(suberer_node.getAttribute('height'))
687 if (suberer_node.hasAttribute('parent')):
688 temp_element_set['parent'] = suberer_node.getAttribute('parent')
690 if (suberer_node.hasAttribute('target')):
691 temp_element_set['target'] = suberer_node.getAttribute('target')
693 if (suberer_node.hasAttribute('text')):
694 temp_element_set['text'] = suberer_node.getAttribute('text')
696 temp_element_set['type'] = suberer_node.nodeName
697 temp_menu_def['elements'][temp_element_set['name']] = temp_element_set
698 temp_element_set = {}
700 self.files[filename]['menu_defs'][temp_menu_def['name']] = temp_menu_def
702 temp_menu_def = {}
703 temp_element_set = {}
705 if (node.nodeName == 'instance'):
707 for sub_node in node.childNodes:
709 if (sub_node.nodeName == 'object'):
710 object_instances_d.append(sub_node.childNodes[0].nodeValue)
712 if (sub_node.nodeName == 'menu'):
713 menu_instances.append(sub_node.childNodes[0].nodeValue)
715 if (parent != ''):
716 self.files[parent]['children'].append(filename)
717 self.files[filename]['parent'] = parent
719 # create instances
721 for menuname, menu_data in self.files[filename]['menu_defs'].iteritems():
722 self.files[filename]['menu_instances'][menuname] = Menu(menu_def=menu_data)
724 for menuname in menu_instances:
725 if (self.files[filename]['menu_instances'].has_key(menuname)):
726 self.files[filename]['menu_instances'][menuname].show()
728 for file in self.files.keys():
729 if self.files[file]['menu_instances'].has_key(menuname):
730 self.files[file]['menu_instances'][menuname].show()
732 for objectname in object_instances_d:
733 self.addObject(objectname)
735 return 1
736 return 0
737 # ending 2-space formatting
739 def removeFile(self, filename):
741 if (self.files.has_key(filename)):
743 for child in self.files[filename]['children']:
744 self.removeFile(child)
746 del self.files[filename]['children']
748 parent = self.files[filename]['parent']
749 self.files[parent].pop(self.files[parent]['children'].index(filename))
751 del self.files[filename]
753 return
755 def getVisibleMenus(self):
757 menus = {}
759 for file, contents in self.files.iteritems():
760 for name, menu in contents['menu_instances'].iteritems():
761 if not menu.hidden:
762 menus[name] = menu
764 return menus
766 def hideAllMenus(self):
768 for file, contents in self.files.iteritems():
769 for name, menu in contents['menu_instances'].iteritems():
770 menu.hide()
772 return
774 def showMenu(self, menu_name):
776 for file, contents in self.files.iteritems():
777 for name, menu in contents['menu_instances'].iteritems():
778 if contents['menu_instances'].has_key(menu_name):
779 contents['menu_instances'][menu_name].show()
781 return
783 def hideMenu(self, menu_name):
785 for file, contents in self.files:
786 for name, menu in contents['menu_instances'].iteritems():
787 if contents['menu_instances'].has_key(menu_name):
788 contents['menu_instances'][menu_name].hide()
790 return
792 def setMenu(self, menu_name):
794 self.hideAllMenus()
795 self.showMenu(menu_name)
797 return
799 def addObject(self, objectname):
801 for file in self.files.keys():
802 if self.files[file]['object_defs'].has_key(objectname):
803 self.files[file]['object_instances'][objectname] = GameObject(
804 self.files[file]['object_defs'][objectname])
806 return
808 def removeObject(self, objectname):
810 for file in self.files.keys():
811 if self.files[file]['object_defs'].has_key(objectname):
812 del self.files[file]['object_instances'][objectname]
814 return
816 def addListItem(self, menuname, item, data, dvalue):
818 for file in self.files:
819 if self.files[file]['menu_instances'].has_key(menuname):
820 if self.files[file]['menu_instances'][menuname].widgets.has_key(item):
821 the_widget = self.files[file]['menu_instances'][menuname].widgets[item]
823 the_widget.add(data, value=dvalue)
824 the_widget.resize()
825 the_widget.repaint()
827 return
829 def clearListItem(self, menuname, item):
831 for file in self.files:
832 if self.files[file]['menu_instances'].has_key(menuname):
833 if self.files[file]['menu_instances'][menuname].widgets.has_key(item):
834 the_widget = self.files[file]['menu_instances'][menuname].widgets[item]
836 the_widget.clear()
837 the_widget.resize()
838 the_widget.repaint()
840 return
842 def removeListItem(self, menuname, item, value):
844 for file in self.files:
845 if self.files[file]['menu_instances'].has_key(menuname):
846 if self.files[file]['menu_instances'][menuname].has_key(item):
847 the_widget = self.files[file]['menu_instances'][menuname][item]
849 the_widget.remove(value)
850 the_widget.resize()
851 the_widget.repaint()
853 return
855 def getListValue(self, menuname, item):
857 for file in self.files:
858 if self.files[file]['menu_instances'].has_key(menuname):
860 if self.files[file]['menu_instances'][menuname].widgets.has_key(item):
861 the_widget = self.files[file]['menu_instances'][menuname].widgets[item]
863 return the_widget.value
865 return ''
867 def getImage(self, filename):
869 the_buf = pygame.image.load(self.getStringIOFile(filename))
871 return the_buf
873 def getStringIOFile(self, filename):
875 for zip_file in self.zipfiles:
876 for file in zip_file.namelist():
878 if (filename == file):
880 the_string_io = StringIO.StringIO()
881 print >>the_string_io, zip_file.read(file)
882 the_string_io.seek(0)
884 return the_string_io
885 return ''
887 def getStringData(self, filename):
888 for zip_file in self.zipfiles:
889 for file in zip_file.namelist():
891 if (filename == file):
892 return zip_file.read(file)
893 return ''
895 def killThreadGame(self):
897 reactor.stop()
899 return
901 def killGame(self):
903 reactor.callFromThread(self.killThreadGame)
905 return
907 class Menu:
909 def __init__(self, menu_def):
911 self.menu_def = menu_def
912 self.widgets = {}
914 for name, element in menu_def['elements'].iteritems():
916 multiplier_x = float(the_engine.config['window_size'][0]) / 100.00
917 multiplier_y = float(the_engine.config['window_size'][1]) / 100.00
919 dx = float(element['x']) * multiplier_x
920 dy = float(element['y']) * multiplier_y
922 dwidth = float(element['width']) * multiplier_x
923 dheight = float(element['height']) * multiplier_y
925 if (element['type'] == 'button'):
926 self.widgets[name] = pgui.Button(element['text'].encode(), width=dwidth, height=dheight)
927 self.widgets[name].connect(pgui.CLICK, self.clicked, name)
929 if (element['type'] == 'image'):
930 self.widgets[name] = pgui.Image(the_engine.getImage(element['text']))
932 if (element['type'] == 'label'):
933 self.widgets[name] = pgui.Label(element['text'])
935 if (element['type'] == 'listbox'):
936 self.widgets[name] = pgui.List(width=dwidth, height=dheight)
937 self.widgets[name].connect(pgui.CLICK, self.clicked, name)
939 if (self.widgets.has_key(name)):
940 self.widgets[name].resize(width=dwidth, height=dheight)
941 else:
942 print "Menu.__init__(): Widget type", element['type'], " not implemented yet, skipping."
944 self.hidden = 1
946 def show(self):
948 global the_engine
950 multiplier_x = float(the_engine.config['window_size'][0]) / 100.00
951 multiplier_y = float(the_engine.config['window_size'][1]) / 100.00
953 if (self.hidden == 1):
954 for name, element in self.menu_def['elements'].iteritems():
955 dx = float(element['x']) * multiplier_x
956 dy = float(element['y']) * multiplier_y
958 if self.widgets.has_key(name):
959 the_engine.main_container.add(self.widgets[name], dx, dy)
961 self.hidden = 0
963 return
965 def hide(self):
967 global the_engine
969 if (self.hidden != 1):
970 for name, element in self.menu_def['elements'].iteritems():
972 if (self.widgets.has_key(name)):
973 the_engine.main_container.remove(self.widgets[name])
975 self.hidden = 1
977 return
979 def clicked(self, widget):
981 if self.menu_def['elements'].has_key(widget):
983 if self.menu_def['elements'][widget]['target'] != '':
984 exec(self.menu_def['elements'][widget]['target'])
986 the_engine.events.addEvent(['WIDGET_CLICKED',
987 {'name': widget, 'menu_name': self.menu_def['name']}])
989 return
991 class GameObject:
993 def __init__(self, dmold):
995 self.mold = dmold
996 global the_functions
997 global in_script
999 if self.mold['script'] != '':
1001 in_script = 1
1003 the_file = the_engine.getStringData(self.mold['script'])
1004 if the_file != '':
1005 exec(the_file)
1007 in_script = 0
1008 self.my_functions = the_functions
1010 the_functions = {}
1012 def event(self, event, data):
1014 if self.my_functions.has_key(event):
1016 self.my_functions[event](data)
1018 return
1020 def main():
1021 # parse command line stuff
1023 if (len(sys.argv) > 1):
1024 config = sys.argv[1]
1025 else:
1026 print "main(): No config specified, using", CONFIG
1027 config = CONFIG
1029 configuration = parse_config(config)
1031 if (configuration.has_key('error') and configuration['error']):
1032 print "main(): Error in parsing config."
1034 the_event_receiver = EventReceiver()
1036 global client_params
1037 client_params = {'broadcast_port':configuration['broadcast_port'],
1038 'broadcast_bind':configuration['broadcast_bind'],
1039 'message_port':configuration['message_port'],
1040 'name':configuration['name']}
1042 global the_engine
1043 global the_client
1045 the_engine = Engine(configuration)
1047 the_client = Client()
1048 the_client_thread = threading.Thread(target=run_net)
1050 the_client.init(client_params)
1052 the_client_thread.start()
1053 the_engine.run()
1055 the_engine.killGame()
1057 sys.exit()
1059 the_client_thread.join()
1061 return
1063 def run_net():
1065 global client_params
1066 global the_multicast
1068 the_multicast = Multicast()
1069 config = client_params
1071 reactor.listenMulticast(config['broadcast_bind'], the_multicast)
1072 reactor.listenUDP(config['message_port'], the_client)
1074 reactor.run(installSignalHandlers=0)
1076 return
1078 def parse_config(filename):
1079 results = {'error': 1}
1081 if (exists(filename)):
1082 dom = parse(filename)
1083 else:
1084 print "parse_config():", filename, "doesn't exist."
1085 return results
1087 if (dom.childNodes[0].nodeName == 'config'):
1088 for node in dom.childNodes[0].childNodes:
1090 if (node.nodeName == 'window_title'):
1091 results['window_title'] = node.childNodes[0].nodeValue
1093 if (node.nodeName == 'log'):
1094 results['log'] = node.childNodes[0].nodeValue
1096 if (node.nodeName == 'name'):
1097 results['name'] = node.childNodes[0].nodeValue
1099 if (node.nodeName == 'font'):
1100 results['font'] = node.childNodes[0].nodeValue
1102 if (node.nodeName == 'init'):
1103 results['init'] = node.childNodes[0].nodeValue
1105 if (node.nodeName == 'message_port'):
1106 results['message_port'] = int(node.childNodes[0].nodeValue)
1108 if (node.nodeName == 'broadcast_port'):
1109 results['broadcast_port'] = int(node.childNodes[0].nodeValue)
1111 if (node.nodeName == 'broadcast_bind'):
1112 results['broadcast_bind'] = int(node.childNodes[0].nodeValue)
1114 if (node.nodeName == 'fullscreen'):
1115 results['fullscreen'] = int(node.childNodes[0].nodeValue)
1117 if (node.nodeName == 'background_color'):
1119 string_parts = node.childNodes[0].nodeValue.split()
1120 results['background_color'] = [float(string_parts[0]), float(string_parts[1])]
1121 results['background_color'].append(float(string_parts[2]))
1122 results['background_color'].append(float(string_parts[3]))
1124 if (node.nodeName == 'window_size'):
1126 string_parts = node.childNodes[0].nodeValue.split()
1127 results['window_size'] = ((int(string_parts[0]), int(string_parts[1])))
1129 if (node.nodeName == 'gravity'):
1131 string_parts = node.childNodes[0].nodeValue.split()
1132 results['gravity'] = [float(string_parts[0]), float(string_parts[1])]
1133 results['gravity'].append(float(string_parts[2]))
1135 if (node.nodeName == 'step_size'):
1136 results['step_size'] = float(node.childNodes[0].nodeValue)
1138 if (node.nodeName == 'pack_dir'):
1139 results['pack_dir'] = node.childNodes[0].nodeValue
1141 results['error'] = 0
1143 return results
1145 if __name__ == '__main__':
1146 main()