1 // -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // vi:tw=80:et:ts=2:sts=2 3 // 4 // ----------------------------------------------------------------------- 5 // 6 // This file is part of RLVM, a RealLive virtual machine clone. 7 // 8 // ----------------------------------------------------------------------- 9 // 10 // Copyright (C) 2006, 2007 Elliot Glaysher 11 // 12 // This program is free software; you can redistribute it and/or modify 13 // it under the terms of the GNU General Public License as published by 14 // the Free Software Foundation; either version 3 of the License, or 15 // (at your option) any later version. 16 // 17 // This program is distributed in the hope that it will be useful, 18 // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 // GNU General Public License for more details. 21 // 22 // You should have received a copy of the GNU General Public License 23 // along with this program; if not, write to the Free Software 24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 25 // 26 // ----------------------------------------------------------------------- 27 28 #ifndef SRC_SYSTEMS_BASE_SYSTEM_H_ 29 #define SRC_SYSTEMS_BASE_SYSTEM_H_ 30 31 #include <boost/serialization/access.hpp> 32 #include <boost/serialization/version.hpp> 33 #include <boost/filesystem/path.hpp> 34 35 #include <map> 36 #include <sstream> 37 #include <string> 38 #include <utility> 39 #include <vector> 40 41 class GraphicsSystem; 42 class EventSystem; 43 class TextSystem; 44 class SoundSystem; 45 class RLMachine; 46 class Gameexe; 47 class GameexeInterpretObject; 48 class Platform; 49 50 // Syscom Constants 51 // 52 // Associations between syscom integer values and their names. 53 const int NUM_SYSCOM_ENTRIES = 32; 54 const int SYSCOM_INVISIBLE = 0; 55 const int SYSCOM_VISIBLE = 1; 56 const int SYSCOM_GREYED_OUT = 2; 57 58 const int SYSCOM_SAVE = 0; 59 const int SYSCOM_LOAD = 1; 60 const int SYSCOM_MESSAGE_SPEED = 2; 61 const int SYSCOM_WINDOW_ATTRIBUTES = 3; 62 const int SYSCOM_VOLUME_SETTINGS = 4; 63 const int SYSCOM_SCREEN_MODE = 5; 64 const int SYSCOM_MISCELLANEOUS_SETTINGS = 6; 65 // No 7? 66 const int SYSCOM_VOICE_SETTINGS = 8; 67 const int SYSCOM_FONT_SELECTION = 9; 68 const int SYSCOM_BGM_FADE = 10; 69 const int SYSCOM_BGM_SETTINGS = 11; 70 const int SYSCOM_WINDOW_DECORATION_STYLE = 12; 71 const int SYSCOM_AUTO_MODE_SETTINGS = 13; 72 const int SYSCOM_RETURN_TO_PREVIOUS_SELECTION = 14; 73 const int SYSCOM_USE_KOE = 15; 74 const int SYSCOM_DISPLAY_VERSION = 16; 75 const int SYSCOM_SHOW_WEATHER = 17; 76 const int SYSCOM_SHOW_OBJECT_1 = 18; 77 const int SYSCOM_SHOW_OBJECT_2 = 19; 78 const int SYSCOM_CLASSIFY_TEXT = 20; // ??????? Unknown function. 79 const int SYSCOM_GENERIC_1 = 21; 80 const int SYSCOM_GENERIC_2 = 22; 81 // No 23? 82 const int SYSCOM_OPEN_MANUAL_PATH = 24; 83 const int SYSCOM_SET_SKIP_MODE = 25; 84 const int SYSCOM_AUTO_MODE = 26; 85 // No 27? 86 const int SYSCOM_MENU_RETURN = 28; 87 const int SYSCOM_EXIT_GAME = 29; 88 const int SYSCOM_HIDE_MENU = 30; 89 const int SYSCOM_SHOW_BACKGROUND = 31; 90 91 // File type constants. 92 // 93 // These constant, externed vectors are passed as parameters to 94 // FindFile to control which file types are searched for. Defaults to 95 // all. 96 extern const std::vector<std::string> OBJ_FILETYPES; 97 extern const std::vector<std::string> IMAGE_FILETYPES; 98 extern const std::vector<std::string> PDT_IMAGE_FILETYPES; 99 extern const std::vector<std::string> GAN_FILETYPES; 100 extern const std::vector<std::string> ANM_FILETYPES; 101 extern const std::vector<std::string> HIK_FILETYPES; 102 extern const std::vector<std::string> SOUND_FILETYPES; 103 extern const std::vector<std::string> KOE_ARCHIVE_FILETYPES; 104 extern const std::vector<std::string> KOE_LOOSE_FILETYPES; 105 106 // Struct containing the global memory to get serialized to disk with 107 // global memory. 108 struct SystemGlobals { 109 SystemGlobals(); 110 111 // Whether we should put up a yes/no dialog box when saving/loading. 112 bool confirm_save_load_; 113 114 // I suspect that this is a placebo. I'll track the value, but I don't think 115 // it's relevant to anything. 116 bool low_priority_; 117 118 // boost::serialization support 119 template <class Archive> serializeSystemGlobals120 void serialize(Archive& ar, const unsigned int version) { 121 ar& confirm_save_load_; 122 123 if (version > 0) 124 ar& low_priority_; 125 } 126 }; 127 128 BOOST_CLASS_VERSION(SystemGlobals, 1) 129 130 // The system class provides a generalized interface to all the 131 // components that make up a local system that may need to be 132 // implemented differently on different systems, i.e., sound, 133 // graphics, filesystem etc. 134 // 135 // The base System class is an abstract base class that is meant to be 136 // specialized. 137 class System { 138 public: 139 System(); 140 virtual ~System(); 141 confirm_save_load()142 bool confirm_save_load() const { return globals_.confirm_save_load_; } set_confirm_save_load(const int in)143 void set_confirm_save_load(const int in) { globals_.confirm_save_load_ = in; } 144 low_priority()145 bool low_priority() const { return globals_.low_priority_; } set_low_priority(const int in)146 void set_low_priority(const int in) { globals_.low_priority_ = in; } 147 platform()148 std::shared_ptr<Platform> platform() { return platform_; } 149 void SetPlatform(const std::shared_ptr<Platform>& platform); 150 151 // Whether we're currently forcing fast forward (only used during game tests 152 // to zoom through). force_fast_forward()153 bool force_fast_forward() { return force_fast_forward_; } 154 // Set in lua_rlvm, to speed through the game with maximum speed! set_force_fast_forward()155 void set_force_fast_forward() { force_fast_forward_ = true; } 156 force_wait()157 bool force_wait() { return force_wait_; } set_force_wait(bool in)158 void set_force_wait(bool in) { force_wait_ = in; } 159 160 // We record what the text encoding response was during the first scene, and 161 // then during every scene change, if it was western, we flip this bit to 162 // true. We do this as a big hack because we only have System access while 163 // we're loading fonts. use_western_font()164 bool use_western_font() { return use_western_font_; } set_use_western_font()165 void set_use_western_font() { use_western_font_ = true; } 166 167 // Takes and restores the previous selection snapshot; a special emphemeral 168 // save game slot that autosaves on selections and is restored through a 169 // special kepago method/syscom call. 170 void TakeSelectionSnapshot(RLMachine& machine); 171 void RestoreSelectionSnapshot(RLMachine& machine); 172 173 // Syscom related functions 174 // 175 // RealLive provides a context menu system to handle most actions 176 // and configuration settings. The system command menu is configured 177 // with the \#SYSCOM variables in gameexe.ini. It can be disabled by 178 // setting \#SYSCOM_USE to 0, and if a \#CANCELCALL hook is defined it 179 // will never be used at all (Clannad does this, although it uses 180 // the internal flags associated with the system command menu to 181 // control its own menu system). 182 // 183 // These functions are used to manipulate the visibility, change the 184 // values of, and invoke standard dialogs for various SYSCOM elements. 185 186 // Checks the visibility of a single syscom command. Returns 0 if the given 187 // system command is invisible, 1 if it is visible, and 2 if it is visible 188 // but disabled (greyed out). 189 int IsSyscomEnabled(int syscom); 190 191 // Hides all syscom entries 192 void HideSyscom(); 193 194 // Hides the syscom entry |syscom| 195 void HideSyscomEntry(int syscom); 196 197 // Enables all syscom entries 198 void EnableSyscom(); 199 200 // Enables the syscom entry |syscom| 201 void EnableSyscomEntry(int syscom); 202 203 // Disables all syscom entries 204 void DisableSyscom(); 205 206 // Disables the syscom entry |syscom| 207 void DisableSyscomEntry(int syscom); 208 209 // Reads the corresponding value for syscom number |syscom| 210 int ReadSyscom(int syscom); 211 212 // Called by various LongOperations to show the right click menu. 213 void ShowSyscomMenu(RLMachine& machine); 214 215 // If there is a standard dialog box associated with syscom, it is 216 // displayed; if there is a standard action, it is performed. The list of 217 // menu commands in section 4.5 has details of which menu commands have 218 // standard dialogs. The optional value is used for the setting where 219 // relevant (for example, InvokeSyscom(5, val) is exactly equivalent to 220 // SetScreenMode(val)). 221 void InvokeSyscom(RLMachine& machine, int syscom); 222 223 // Shows a screen with certain information about the current state of the 224 // interpreter. 225 void ShowSystemInfo(RLMachine& machine); 226 227 // Finds a file on disk based on its basename with a list of possible 228 // extensions, or empty() if file not found. 229 boost::filesystem::path FindFile(const std::string& fileName, 230 const std::vector<std::string>& extensions); 231 232 // Resets the present values of the system; this doesn't clear user settings, 233 // but clears things like the current graphics state and the status of all 234 // the text windows. This method is called when the user loads a game or 235 // resets the machine. The System implementation of reset() will call 236 // reset() on all systems. 237 void Reset(); 238 239 // Returns the global state for saving/restoring globals()240 SystemGlobals& globals() { return globals_; } 241 242 // Cleans the regname entry from the gameexe and makes it filesystem 243 // safe. This translates it to UTF-8, as Gameexe files are written in 244 // Shift-JIS. 245 std::string Regname(); 246 247 // Returns a boost::filesystem object which points to the directory 248 // where saved game data, preferences, etc should be stored 249 // for this game. 250 // 251 // The default implementation returns "~/.rlvm/#{REGNAME}/". A Mac 252 // specific override could return "~/Library/Application 253 // Support/rlvm/#{REGNAME}/" 254 boost::filesystem::path GameSaveDirectory(); 255 256 // Testing and Debugging Tools 257 258 // Whether we are zooming through text and events quickly. Currently can be 259 // triggered by holding down the control key, or using skip previously read 260 // text. 261 bool ShouldFastForward(); 262 263 // Renders the screen and dumps a textual representation of the screen. 264 void DumpRenderTree(RLMachine& machine); 265 266 // Called once per gameloop. 267 virtual void Run(RLMachine& machine) = 0; 268 269 // Returns the specific subclasses. 270 virtual GraphicsSystem& graphics() = 0; 271 virtual EventSystem& event() = 0; 272 virtual Gameexe& gameexe() = 0; 273 virtual TextSystem& text() = 0; 274 virtual SoundSystem& sound() = 0; 275 276 protected: 277 // Native widget drawer. Can be NULL. This field is protected instead of 278 // private because we need to be destroy the Platform before we destroy SDL. 279 std::shared_ptr<Platform> platform_; 280 281 private: 282 typedef std::multimap<std::string, 283 std::pair<std::string, boost::filesystem::path>> 284 FileSystemCache; 285 286 boost::filesystem::path GetHomeDirectory(); 287 288 // Invokes a custom dialog or the standard one if none present. 289 void InvokeSaveOrLoad(RLMachine& machine, 290 int syscom, 291 const std::string& mod_key, 292 const std::string& location); 293 294 // Verify that |index| is valid and throw if it isn't. 295 void CheckSyscomIndex(int index, const char* function); 296 297 // Builds a list of all files that are in a directory specified in the 298 // #FOLDNAME part of the Gameexe.ini file. 299 void BuildFileSystemCache(); 300 301 // Recurses on |directory| and adds all filetypes that we can read to our 302 // FileSystemCache. 303 void AddDirectoryToCache(const boost::filesystem::path& directory); 304 305 // The visibility status for all syscom entries 306 int syscom_status_[NUM_SYSCOM_ENTRIES]; 307 308 // Whether the SYSCOM menu is currently being displayed. 309 bool in_menu_; 310 311 // Whether we are being forced to fast forward through the game for testing 312 // reasons. 313 bool force_fast_forward_; 314 315 // Forces a 10ms sleep at the end of the System::run function. Used to lower 316 // CPU usage during manual redrawing. 317 bool force_wait_; 318 319 // Whether we should be trying to find a western font. 320 bool use_western_font_; 321 322 // Cached view of the filesystem, mapping a lowercase filename to an 323 // extension and the local file path for that file. 324 FileSystemCache filesystem_cache_; 325 326 SystemGlobals globals_; 327 328 // A stream with the save game data at the time of the last selection. Used 329 // for the Return to Previous Selection feature. 330 std::shared_ptr<std::stringstream> previous_selection_; 331 332 // Implementation detail which resets in_menu_; 333 friend class MenuReseter; 334 335 friend class boost::serialization::access; 336 337 // boost::serialization 338 template <class Archive> serialize(Archive & ar,unsigned int version)339 void serialize(Archive& ar, unsigned int version) { 340 // For now, does nothing 341 } 342 }; 343 344 // ----------------------------------------------------------------------- 345 346 // Returns a version string suitable for printing. Used on the command line 347 // interface and on the info screen. 348 std::string GetRlvmVersionString(); 349 350 #endif // SRC_SYSTEMS_BASE_SYSTEM_H_ 351