# Balazar # Copyright (C) 2002-2003 Bertrand LAMY, Jean-Baptiste LAMY # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # This file contain these classes : # - MainMenu # - MainMenuIdler # - Rectangle # - MsgWindow # - ConfigKey import sys, os, os.path, random, math import soya, soya.opengl as soyaopengl import soya.sdlconst as soyasdlconst import soya.widget as widget import balazar import balazar.globdef as globdef from balazar.controller import CONTROLS COLOR = (0.0, 0.0, 0.0, 1.0) HIGHLIGHT = (0.0, 0.0, 1.0, 1.0) def filter_string(s): return s.replace("\r", "").replace("\n", "") class Rectangle(soya.widget.Widget): def __init__(self, master = None, color = (1.0, 1.0, 1.0, 0.8)): soya.widget.Widget.__init__(self, master) self.color = color self.visible = 1 def render(self): if self.visible: if self.color[3] < 1.0: soyaopengl.glEnable(soyaopengl.GL_BLEND) soyaopengl.glColor4f (*self.color) soyaopengl.glBegin (soyaopengl.GL_QUADS) soyaopengl.glVertex2f(self.left, self.top) soyaopengl.glVertex2f(self.left, self.top + self.height) soyaopengl.glVertex2f(self.left + self.width, self.top + self.height) soyaopengl.glVertex2f(self.left + self.width, self.top) soyaopengl.glEnd() if self.color[3] < 1.0: soyaopengl.glDisable(soyaopengl.GL_BLEND) class MainMenuIdler(soya.Idler): def __init__ (self, mainmenu): soya.Idler.__init__ (self) self.mainmenu = mainmenu self.step = 0 def begin_round(self): soya.Idler.begin_round(self) if self.step == 0: for event in soya.process_event(): if (event[0] == soyasdlconst.JOYBUTTONDOWN) or (event[0] == soyasdlconst.KEYDOWN and event[1]) or (event[0] == soyasdlconst.MOUSEBUTTONDOWN): self.mainmenu.set_current_menu(self.mainmenu.game_menu_1) self.mainmenu.bg_rect.visible = 1 self.step = 1 break elif self.mainmenu.current_menu: for event in soya.process_event(): self.mainmenu.current_menu.process_event(event) class MainMenu: def __init__(self): self.current_menu = None self.old_menus = [] self.root = widget.Group() self.bg_img = soya.widget.Image(self.root, soya.Material.get('splash')) self.bg_img.resize_style = ('maximize', ('keep ratio', 1024 / 768.0), 'center x', 'center y') self.bg_img.resize_style = ('maximize', 'center x', 'center y') self.bg_rect = Rectangle(self.root) self.bg_rect.resize_style = ('maximize', ('percent top', 0.4), 'maximize height', ('margin bottom', 20), ('margin left', 20), ('margin right', 20)) self.bg_rect.visible = 0 self.scene = soya.World() self.atm = soya.NoBackgroundAtmosphere() self.atm.ambient = (0.2, 0.2, 0.2, 1.0) self.scene.atmosphere = self.atm CHOICELIST_RESIZE_STYLE = ('maximize', ('percent top', 0.4), 'maximize height', ('margin bottom', 20)) self.game_menu_1 = soya.widget.ChoiceList(self.root, [ soya.widget.Choice(_('Play solo game' ), self.show_solo), soya.widget.Choice(_('Play multiplayer game'), self.show_multi), soya.widget.Choice(_('Hardware options' ), self.show_h_option), soya.widget.Choice(_('Keyboard options' ), self.show_key_option), soya.widget.Choice(_('Quit' ), self.go_back) ], None, COLOR, HIGHLIGHT, cancel = -1) self.game_menu_1.resize_style = CHOICELIST_RESIZE_STYLE self.game_menu_1.visible = 0 checkbox = [_('off'), _('on')] self.menu_h_option = soya.widget.ChoiceList(self.root, [ soya.widget.Choice(_('Resolution'), None, None, ['320x240', '640x480', '800x600', '1024x768', '1152x864', '1280x800', '1280x1024', '1400x1050', '1680x1050']), soya.widget.Choice(_('Fullscreen'), None, None, checkbox), soya.widget.Choice(_('Graphic quality'), None, None, [_('Low'), _('Medium'), _('High')]), soya.widget.Choice(_('Sounds'), None, None, checkbox), soya.widget.Choice(_('Music'), None, None, checkbox), soya.widget.Choice(_('Async load music'), None, None, checkbox), soya.widget.Choice(_('Sound system'), None, None, ["OpenAL", "SDL_mixer"]), soya.widget.ChoiceInput(_('Saved game directory')), soya.widget.Choice(_('Back'), self.back_h_option) ], None, COLOR, HIGHLIGHT, cancel = -1) self.menu_h_option.resize_style = CHOICELIST_RESIZE_STYLE self.menu_h_option.visible = 0 self.label = widget.Group(self.root) self.label.visible = 0 self.label.process_event = lambda event: self.menu_label.process_event(event) self.menu_label = soya.widget.ChoiceList(self.label, [ soya.widget.Choice( u"" , None, None, [""]), soya.widget.Choice(_('Back'), self.go_back), ], None, COLOR, HIGHLIGHT, cancel = -1) self.menu_label.resize_style = ('maximize', ('percent top', 0.4), 'maximize height', ('margin top', 30), ('margin bottom', 20)) self.solo = widget.Group(self.root) self.solo.visible = 0 self.solo.process_event = lambda event: self.menu_solo.process_event(event) self.menu_solo = soya.widget.ChoiceList(self.solo, [ soya.widget.Choice (_('Start'), self.play_solo), soya.widget.ChoiceInput(_('Player name (new name => new game)')), soya.widget.Choice (_('Back'), self.go_back), ], None, COLOR, HIGHLIGHT, cancel = -1) self.menu_solo.resize_style = ('maximize', ('percent top', 0.4), 'maximize height', ('margin top', 30), ('margin bottom', 20)) self.multi = widget.Group(self.root) self.multi.visible = 0 self.multi.process_event = lambda event: self.menu_multi.process_event(event) self.menu_multi = soya.widget.ChoiceList(self.multi, [ soya.widget.Choice (_('Start'), self.play_multi), soya.widget.ChoiceInput(_('Player name (new name to create new game)')), soya.widget.ChoiceInput(_('Password')), soya.widget.ChoiceInput(_('Remote host or IP')), soya.widget.ChoiceInput(_('Connect to port')), soya.widget.Choice (_('Back'), self.go_back), ], None, COLOR, HIGHLIGHT, cancel = -1) self.menu_multi.resize_style = ('maximize', ('percent top', 0.4), 'maximize height', ('margin top', 30), ('margin bottom', 20)) def set_current_menu(self, menu): if self.current_menu: self.current_menu.visible = 0 self.old_menus.append(self.current_menu) self.current_menu = menu self.current_menu.visible = 1 def go_back(self): if len(self.old_menus) == 0: globdef.generate_dot_balazar() soya.IDLER.stop() import sys sys.exit() if self.current_menu: self.current_menu.visible = 0 self.current_menu = self.old_menus.pop() self.current_menu.visible = 1 def show_h_option(self): self.menu_h_option.choices[0].value = str(globdef.SCREEN_WIDTH) + 'x' + str(globdef.SCREEN_HEIGHT) self.menu_h_option.choices[1].value = self.menu_h_option.choices[1].range[globdef.FULLSCREEN] self.menu_h_option.choices[2].value = self.menu_h_option.choices[2].range[globdef.QUALITY] self.menu_h_option.choices[3].value = self.menu_h_option.choices[3].range[globdef.SOUND] self.menu_h_option.choices[4].value = self.menu_h_option.choices[4].range[globdef.MUSIC] self.menu_h_option.choices[5].value = self.menu_h_option.choices[5].range[globdef.ASYNC_LOAD_MUSIC] self.menu_h_option.choices[6].value = globdef.SOUND_SYSTEM self.menu_h_option.choices[7].value = globdef.SAVED_GAME_DIR self.set_current_menu(self.menu_h_option) def back_h_option(self): resa = self.menu_h_option.choices[0].value globdef.SCREEN_WIDTH = int(resa[: resa.find("x")]) globdef.SCREEN_HEIGHT = int(resa[resa.find("x") + 1:]) globdef.FULLSCREEN = (self.menu_h_option.choices[1].value == _('on')) globdef.QUALITY = self.menu_h_option.choices[2].range.index(self.menu_h_option.choices[2].value) globdef.SOUND = (self.menu_h_option.choices[3].value == _('on')) globdef.MUSIC = (self.menu_h_option.choices[4].value == _('on')) globdef.ASYNC_LOAD_MUSIC = (self.menu_h_option.choices[5].value == _('on')) globdef.SOUND_SYSTEM = self.menu_h_option.choices[6].value globdef.SAVED_GAME_DIR = self.menu_h_option.choices[7].value soya.set_quality(globdef.QUALITY) soya.set_video(globdef.SCREEN_WIDTH, globdef.SCREEN_HEIGHT, globdef.FULLSCREEN, 1) import balazar.sound; reload(balazar.sound) self.go_back() def show_solo(self): self.menu_solo.choices[1].value = globdef.NAME self.set_current_menu(self.solo) def play_solo(self): idler = soya.IDLER globdef.NAME = filter_string(self.menu_solo.choices[1].value) try: r = balazar.game_interface.start_single(globdef.NAME, "test") except: error, value, traceback = sys.exc_info() sys.excepthook(error, value, traceback) r = "%s(%s)" % (error, value) soya.set_root_widget(self.root) idler.reset() soya.IDLER = idler if r: self.message("Error: " + str(r)) def show_multi(self): self.menu_multi.choices[1].value = globdef.NAME self.menu_multi.choices[2].value = globdef.PASSWORD self.menu_multi.choices[3].value = globdef.SERVER_HOST self.menu_multi.choices[4].value = str(globdef.SERVER_PORT) self.set_current_menu(self.multi) def play_multi(self): idler = soya.IDLER globdef.NAME = filter_string(self.menu_multi.choices[1].value) globdef.PASSWORD = filter_string(self.menu_multi.choices[2].value) globdef.SERVER_HOST = filter_string(self.menu_multi.choices[3].value) globdef.SERVER_PORT = int (self.menu_multi.choices[4].value) try: r = balazar.game_interface.start_client(globdef.SERVER_HOST, globdef.NAME, globdef.PASSWORD, globdef.SERVER_PORT) except: error, value, traceback = sys.exc_info() sys.excepthook(error, value, traceback) r = u"%s(%s)" % (error, value) soya.set_root_widget(self.root) idler.reset() soya.IDLER = idler if r: if r != "Connection was closed cleanly.": # Server close the connection, because the player is dead r = str(r) if "111" in r: r = r + u"\n\n" + _("__have_you_forget_the_server_?__") self.message(u"Error: " + r) def message(self, text): self.menu_label.choices[0].label = text self.set_current_menu(self.label) def show_key_option(self): self.keyconfig = widget.Group(self.root) self.keyconfig.visible = 0 self.keyconfig.process_event = lambda event: self.menu_keyconfig.process_event(event) self.menu_keyconfig = soya.widget.ChoiceList(self.keyconfig, [ soya.widget.Choice(CONTROLS.control_label(control), lambda control = control : self.define_control(control)) for control in CONTROLS.controls() ] + [ soya.widget.Choice(_('Back'), self.go_back), ], None, COLOR, HIGHLIGHT, cancel = -1) self.menu_keyconfig.resize_style = ('maximize', ('percent top', 0.4), 'maximize height', ('margin top', 30), ('margin bottom', 20)) self.set_current_menu(self.keyconfig) def define_control(self, control): while 1: for event in soya.process_event(): if event[0] == soyasdlconst.KEYDOWN: CONTROLS.assign_event_to_control(event[1], control) break elif event[0] == soyasdlconst.JOYBUTTONDOWN: CONTROLS.assign_event_to_control(soyasdlconst.K_0 + event[1], control) break else: continue break self.show_key_option() def run (self): soya.set_root_widget(self.root) self.idler = MainMenuIdler(self) action = self.idler.idle()