[653] | 1 | #!/usr/bin/env python |
---|
| 2 | |
---|
| 3 | # This program is free software: you can redistribute it and/or modify |
---|
| 4 | # it under the terms of the GNU General Public License as published by |
---|
| 5 | # the Free Software Foundation, either version 3 of the License, or |
---|
| 6 | # (at your option) any later version. |
---|
| 7 | |
---|
| 8 | # This program is distributed in the hope that it will be useful, |
---|
| 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 11 | # GNU General Public License for more details. |
---|
| 12 | |
---|
| 13 | # You should have received a copy of the GNU General Public License |
---|
| 14 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
| 15 | """This module contains the main Application class |
---|
| 16 | and the basic Listener for PARPG """ |
---|
| 17 | |
---|
[742] | 18 | import os |
---|
[653] | 19 | |
---|
| 20 | from fife import fife |
---|
| 21 | from fife.extensions import pychan |
---|
[748] | 22 | from fife.extensions.serializers.xmlanimation import XMLAnimationLoader |
---|
[653] | 23 | from fife.extensions.basicapplication import ApplicationBase |
---|
| 24 | |
---|
[736] | 25 | from parpg.gamemodel import GameModel |
---|
| 26 | from parpg.mainmenuview import MainMenuView |
---|
| 27 | from parpg import console |
---|
| 28 | from parpg.mainmenucontroller import MainMenuController |
---|
| 29 | from parpg.common.listeners.event_listener import EventListener |
---|
| 30 | from parpg.common.listeners.key_listener import KeyListener |
---|
| 31 | from parpg.common.listeners.mouse_listener import MouseListener |
---|
| 32 | from parpg.common.listeners.command_listener import CommandListener |
---|
| 33 | from parpg.common.listeners.console_executor import ConsoleExecuter |
---|
| 34 | from parpg.common.listeners.widget_listener import WidgetListener |
---|
[653] | 35 | |
---|
| 36 | class KeyFilter(fife.IKeyFilter): |
---|
| 37 | """ |
---|
| 38 | This is the implementation of the fife.IKeyFilter class. |
---|
| 39 | |
---|
| 40 | Prevents any filtered keys from being consumed by guichan. |
---|
| 41 | """ |
---|
| 42 | def __init__(self, keys): |
---|
| 43 | fife.IKeyFilter.__init__(self) |
---|
| 44 | self._keys = keys |
---|
| 45 | |
---|
| 46 | def isFiltered(self, event): |
---|
| 47 | """Checks if an key is filtered""" |
---|
| 48 | return event.getKey().getValue() in self._keys |
---|
| 49 | |
---|
| 50 | class ApplicationListener(KeyListener, |
---|
| 51 | MouseListener, |
---|
| 52 | ConsoleExecuter, |
---|
| 53 | CommandListener, |
---|
| 54 | WidgetListener): |
---|
| 55 | """Basic listener for PARPG""" |
---|
| 56 | |
---|
| 57 | def __init__(self, event_listener, engine, view, model): |
---|
| 58 | """Initialize the instance. |
---|
| 59 | @type engine: fife.engine |
---|
| 60 | @param engine: ??? |
---|
| 61 | @type view: viewbase.ViewBase |
---|
| 62 | @param view: View that draws the current state |
---|
| 63 | @type model: GameModel |
---|
| 64 | @param model: The game model""" |
---|
| 65 | KeyListener.__init__(self, event_listener) |
---|
| 66 | MouseListener.__init__(self, event_listener) |
---|
| 67 | ConsoleExecuter.__init__(self, event_listener) |
---|
| 68 | CommandListener.__init__(self, event_listener) |
---|
| 69 | WidgetListener.__init__(self, event_listener) |
---|
| 70 | self.engine = engine |
---|
| 71 | self.view = view |
---|
| 72 | self.model = model |
---|
| 73 | keyfilter = KeyFilter([fife.Key.ESCAPE]) |
---|
| 74 | keyfilter.__disown__() |
---|
| 75 | |
---|
| 76 | engine.getEventManager().setKeyFilter(keyfilter) |
---|
| 77 | self.quit = False |
---|
| 78 | self.about_window = None |
---|
| 79 | self.console = console.Console(self) |
---|
| 80 | |
---|
| 81 | def quitGame(self): |
---|
| 82 | """Forces a quit game on next cycle. |
---|
| 83 | @return: None""" |
---|
| 84 | self.quit = True |
---|
| 85 | |
---|
| 86 | def onConsoleCommand(self, command): |
---|
| 87 | """ |
---|
| 88 | Called on every console comand, delegates calls to the a console |
---|
| 89 | object, implementing the callbacks |
---|
| 90 | @type command: string |
---|
| 91 | @param command: the command to run |
---|
| 92 | @return: result |
---|
| 93 | """ |
---|
| 94 | return self.console.handleConsoleCommand(command) |
---|
| 95 | |
---|
| 96 | def onCommand(self, command): |
---|
| 97 | """Enables the game to be closed via the 'X' button on the window frame |
---|
| 98 | @type command: fife.Command |
---|
| 99 | @param command: The command to read. |
---|
| 100 | @return: None""" |
---|
| 101 | if(command.getCommandType() == fife.CMD_QUIT_GAME): |
---|
| 102 | self.quit = True |
---|
| 103 | command.consume() |
---|
| 104 | |
---|
| 105 | class PARPGApplication(ApplicationBase): |
---|
| 106 | """Main Application class |
---|
| 107 | We use an MVC model model |
---|
| 108 | self.gamesceneview is our view,self.model is our model |
---|
| 109 | self.controller is the controller""" |
---|
| 110 | |
---|
| 111 | def __init__(self, setting): |
---|
| 112 | """Initialise the instance. |
---|
| 113 | @return: None""" |
---|
[748] | 114 | self._setting = setting |
---|
| 115 | self.engine = fife.Engine() |
---|
| 116 | self.loadSettings() |
---|
| 117 | self.engine.init() |
---|
| 118 | self._animationloader = XMLAnimationLoader(self.engine.getImagePool(), |
---|
| 119 | self.engine.getVFS()) |
---|
| 120 | self.engine.getAnimationPool().addResourceLoader(self._animationloader) |
---|
| 121 | |
---|
[653] | 122 | pychan.init(self.engine, debug = True) |
---|
| 123 | #self.engine.getModel(self) |
---|
| 124 | self.model = GameModel(self.engine, setting) |
---|
| 125 | self.model.maps_file = self._setting.get("PARPG", "MapsFile") |
---|
| 126 | self.model.readMapFiles() |
---|
| 127 | self.model.object_db_file = self._setting.get("PARPG", |
---|
| 128 | "ObjectDatabaseFile") |
---|
| 129 | self.model.readObjectDB() |
---|
| 130 | self.model.agents_directory = self._setting.get("PARPG", |
---|
| 131 | "AgentsDirectory") |
---|
| 132 | self.model.getAgentImportFiles() |
---|
| 133 | self.model.all_agents_file = self._setting.get("PARPG", "AllAgentsFile") |
---|
| 134 | self.model.readAllAgents() |
---|
| 135 | self.model.dialogues_directory = self._setting.get("PARPG", |
---|
| 136 | "DialoguesDirectory") |
---|
| 137 | self.model.getDialogues() |
---|
| 138 | self.view = MainMenuView(self.engine, self.model) |
---|
[743] | 139 | self.fonts_directory = self._setting.get("FIFE", "FontsDirectory") |
---|
[742] | 140 | self.loadFonts(self.fonts_directory) |
---|
[653] | 141 | self.event_listener = EventListener(self.engine) |
---|
| 142 | self.controllers = [] |
---|
| 143 | controller = MainMenuController(self.engine, |
---|
| 144 | self.view, |
---|
| 145 | self.model, |
---|
| 146 | self) |
---|
| 147 | #controller.initHud() |
---|
| 148 | self.controllers.append(controller) |
---|
| 149 | self.listener = ApplicationListener(self.event_listener, |
---|
| 150 | self.engine, |
---|
| 151 | self.view, |
---|
| 152 | self.model) |
---|
| 153 | #start_map = self._setting.get("PARPG", "Map") |
---|
| 154 | #self.model.changeMap(start_map) |
---|
| 155 | |
---|
[742] | 156 | def loadFonts(self, fonts_directory): |
---|
| 157 | file_names = os.listdir(fonts_directory) |
---|
| 158 | for file_name in file_names: |
---|
| 159 | base_name, extension = os.path.splitext(file_name) |
---|
| 160 | if extension == '.fontdef': |
---|
[743] | 161 | pychan.loadFonts(file_name) |
---|
[742] | 162 | |
---|
[748] | 163 | def loadSettings(self): |
---|
| 164 | """ |
---|
| 165 | Load the settings from a python file and load them into the engine. |
---|
| 166 | Called in the ApplicationBase constructor. |
---|
| 167 | """ |
---|
| 168 | |
---|
| 169 | engineSetting = self.engine.getSettings() |
---|
| 170 | engineSetting.setDefaultFontGlyphs(self._setting.fife.FontGlyphs) |
---|
| 171 | engineSetting.setDefaultFontPath(self._setting.fife.Font) |
---|
| 172 | engineSetting.setDefaultFontSize(self._setting.fife.DefaultFontSize) |
---|
| 173 | engineSetting.setBitsPerPixel(self._setting.fife.BitsPerPixel) |
---|
| 174 | engineSetting.setInitialVolume(self._setting.fife.InitialVolume) |
---|
| 175 | engineSetting.setSDLRemoveFakeAlpha(self._setting.fife.SDLRemoveFakeAlpha) |
---|
| 176 | engineSetting.setScreenWidth(self._setting.fife.ScreenWidth) |
---|
| 177 | engineSetting.setScreenHeight(self._setting.fife.ScreenHeight) |
---|
| 178 | engineSetting.setRenderBackend(self._setting.fife.RenderBackend) |
---|
| 179 | engineSetting.setFullScreen(self._setting.fife.FullScreen) |
---|
| 180 | engineSetting.setVideoDriver(self._setting.fife.VideoDriver) |
---|
| 181 | engineSetting.setLightingModel(self._setting.fife.Lighting) |
---|
| 182 | engineSetting.setColorKeyEnabled(self._setting.fife.ColorKeyEnabled) |
---|
| 183 | |
---|
| 184 | key = [int(digit) for digit in self._setting.fife.ColorKey] |
---|
| 185 | engineSetting.setColorKey(*key) |
---|
| 186 | |
---|
| 187 | engineSetting.setWindowTitle(self._setting.fife.WindowTitle) |
---|
| 188 | engineSetting.setWindowIcon(self._setting.fife.WindowIcon) |
---|
| 189 | |
---|
| 190 | try: |
---|
| 191 | engineSetting.setImageChunkSize(self._setting.fife.ImageChunkSize) |
---|
| 192 | except: |
---|
| 193 | pass |
---|
| 194 | |
---|
[738] | 195 | def createListener(self): |
---|
| 196 | """ __init__ takes care of the event listener, basicapplication's |
---|
| 197 | createListener is only harmful. Without overriding it, the program |
---|
| 198 | quit's on esc press, rather than invoking the main menu. |
---|
| 199 | """ |
---|
| 200 | pass |
---|
| 201 | |
---|
[653] | 202 | def pushController(self, controller): |
---|
| 203 | """Adds a controller to the list to be the current active one.""" |
---|
| 204 | self.controllers[-1].pause(True) |
---|
| 205 | self.controllers.append(controller) |
---|
| 206 | |
---|
| 207 | def popController(self): |
---|
| 208 | """Removes and returns the current active controller, unless its the last one""" |
---|
| 209 | ret_controller = None |
---|
| 210 | if self.controllers.count > 1: |
---|
| 211 | ret_controller = self.controllers.pop() |
---|
| 212 | self.controllers[-1].pause(False) |
---|
| 213 | ret_controller.onStop() |
---|
| 214 | return ret_controller |
---|
| 215 | |
---|
| 216 | def switchController(self, controller): |
---|
| 217 | """Clears the controller list and adds a controller to be the current active one""" |
---|
| 218 | for old_controller in self.controllers: |
---|
| 219 | old_controller.onStop() |
---|
| 220 | self.controllers = [] |
---|
| 221 | self.controllers.append(controller) |
---|
| 222 | |
---|
| 223 | def _pump(self): |
---|
| 224 | """Main game loop. |
---|
| 225 | There are in fact 2 main loops, this one and the one in GameSceneView. |
---|
| 226 | @return: None""" |
---|
| 227 | if self.listener.quit: |
---|
| 228 | self.breakRequested = True #pylint: disable-msg=C0103 |
---|
| 229 | else: |
---|
| 230 | for controller in self.controllers: |
---|
[737] | 231 | controller.pump() |
---|