diff --git a/CMakeLists.txt b/CMakeLists.txt index 60eadc49a7..8225b4f374 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,10 +24,12 @@ set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VE configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp") +option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE) option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE) # Sound source selection option(USE_FFMPEG "use ffmpeg for sound" OFF) +option(USE_AUDIERE "use audiere for sound" OFF) option(USE_MPG123 "use mpg123 + libsndfile for sound" ON) find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems") @@ -134,6 +136,13 @@ if (USE_FFMPEG) set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_FFMPEG) endif (USE_FFMPEG) +if (USE_AUDIERE) + find_package(Audiere REQUIRED) + set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${AUDIERE_INCLUDE_DIR}) + set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${AUDIERE_LIBRARY}) + set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_AUDIERE) +endif (USE_AUDIERE) + if (USE_MPG123) find_package(MPG123 REQUIRED) find_package(SNDFILE REQUIRED) @@ -216,6 +225,9 @@ endif (APPLE) # Other files +configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg + "${OpenMW_BINARY_DIR}/settings-default.cfg") + configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local "${OpenMW_BINARY_DIR}/openmw.cfg") configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg @@ -242,8 +254,14 @@ if (APPLE) "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) # prepare plugins - if (${CMAKE_BUILD_TYPE} MATCHES "Release" OR - ${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") + if (${CMAKE_BUILD_TYPE} MATCHES "Release") + set(OPENMW_RELEASE_BUILD 1) + endif() + if (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") + set(OPENMW_RELEASE_BUILD 1) + endif() + + if (${OPENMW_RELEASE_BUILD}) set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL}) else() set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) @@ -290,6 +308,7 @@ if(DPKG_PROGRAM) INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") #Install global configuration files + INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") @@ -328,7 +347,10 @@ if(WIN32) FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*") INSTALL(FILES ${files} DESTINATION ".") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/readme.txt" DESTINATION ".") + INSTALL(FILES + "${OpenMW_SOURCE_DIR}/readme.txt" + "${OpenMW_BINARY_DIR}/settings-default.cfg" + DESTINATION ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") SET(CPACK_GENERATOR "NSIS") @@ -338,8 +360,12 @@ if(WIN32) SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO}) SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) - SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'") + SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;omwlauncher;OpenMW Launcher") + SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'") + SET(CPACK_NSIS_DELETE_ICONS_EXTRA " + !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP + Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\" + ") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt") SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt") SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index 08b05f417e..5503a7c1a8 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -12,12 +12,22 @@ MwIniImporter::MwIniImporter() { const char *map[][2] = { { "fps", "General:Show FPS" }, + { "nosound", "General:Disable Audio" }, { 0, 0 } }; + const char *fallback[] = { + "Weather:Sunrise Time", + "Weather:Sunset Time", + 0 + }; for(int i=0; map[i][0]; i++) { mMergeMap.insert(std::make_pair(map[i][0], map[i][1])); } + + for(int i=0; fallback[i]; i++) { + mMergeFallback.push_back(fallback[i]); + } } void MwIniImporter::setVerbose(bool verbose) { @@ -116,16 +126,38 @@ void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) { multistrmap::iterator iniIt; for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); it++) { if((iniIt = ini.find(it->second)) != ini.end()) { - cfg.erase(it->first); - if(!this->specialMerge(it->first, it->second, cfg, ini)) { - cfg.insert(std::make_pair >(it->first, iniIt->second)); + for(std::vector::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) { + cfg.erase(it->first); + insertMultistrmap(cfg, it->first, *vc); } } } } -bool MwIniImporter::specialMerge(std::string cfgKey, std::string iniKey, multistrmap &cfg, multistrmap &ini) { - return false; +void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) { + cfg.erase("fallback"); + + multistrmap::iterator cfgIt; + multistrmap::iterator iniIt; + for(std::vector::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); it++) { + if((iniIt = ini.find(*it)) != ini.end()) { + for(std::vector::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) { + std::string value(*it); + std::replace( value.begin(), value.end(), ' ', '_' ); + std::replace( value.begin(), value.end(), ':', '_' ); + value.append(",").append(vc->substr(0,vc->length()-1)); + insertMultistrmap(cfg, "fallback", value); + } + } + } +}; + +void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) { + multistrmap::iterator it = cfg.find(key); + if(it == cfg.end()) { + cfg.insert(std::make_pair >(key, std::vector() )); + } + cfg[key].push_back(value); } void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { diff --git a/apps/mwiniimporter/importer.hpp b/apps/mwiniimporter/importer.hpp index 988f10255e..ced332a72d 100644 --- a/apps/mwiniimporter/importer.hpp +++ b/apps/mwiniimporter/importer.hpp @@ -18,14 +18,16 @@ class MwIniImporter { multistrmap loadIniFile(std::string filename); multistrmap loadCfgFile(std::string filename); void merge(multistrmap &cfg, multistrmap &ini); + void mergeFallback(multistrmap &cfg, multistrmap &ini); void importGameFiles(multistrmap &cfg, multistrmap &ini); void writeToFile(boost::iostreams::stream &out, multistrmap &cfg); private: - bool specialMerge(std::string cfgKey, std::string iniKey, multistrmap &cfg, multistrmap &ini); + void insertMultistrmap(multistrmap &cfg, std::string key, std::string value); std::string numberToString(int n); bool mVerbose; strmap mMergeMap; + std::vector mMergeFallback; }; diff --git a/apps/mwiniimporter/main.cpp b/apps/mwiniimporter/main.cpp index 9a6e61645d..234d7d57d4 100644 --- a/apps/mwiniimporter/main.cpp +++ b/apps/mwiniimporter/main.cpp @@ -9,7 +9,8 @@ namespace bpo = boost::program_options; int main(int argc, char *argv[]) { - bpo::options_description desc("Syntax: mwiniimporter \nAllowed options"); + bpo::options_description desc("Syntax: mwiniimporter inifile configfile\nAllowed options"); + bpo::positional_options_description p_desc; desc.add_options() ("help,h", "produce help message") ("verbose,v", "verbose output") @@ -18,28 +19,22 @@ int main(int argc, char *argv[]) { ("output,o", bpo::value()->default_value(""), "openmw.cfg file") ("game-files,g", "import esm and esp files") ; + p_desc.add("ini", 1).add("cfg", 1); bpo::variables_map vm; - try { - bpo::store(boost::program_options::parse_command_line(argc, argv, desc), vm); + bpo::parsed_options parsed = bpo::command_line_parser(argc, argv) + .options(desc) + .positional(p_desc) + .run(); + + bpo::store(parsed, vm); - // parse help before calling notify because we dont want it to throw an error if help is set - if(vm.count("help")) { - std::cout << desc; - return 0; - } + if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) { + std::cout << desc; + return 0; + } - bpo::notify(vm); - - } - catch(std::exception& e) { - std::cerr << "Error:" << e.what() << std::endl; - return -1; - } - catch(...) { - std::cerr << "Error" << std::endl; - return -2; - } + bpo::notify(vm); std::string iniFile = vm["ini"].as(); std::string cfgFile = vm["cfg"].as(); @@ -58,21 +53,22 @@ int main(int argc, char *argv[]) { std::cerr << "cfg file does not exist" << std::endl; return -4; } - + MwIniImporter importer; importer.setVerbose(vm.count("verbose")); - boost::iostreams::stream file(outputFile); MwIniImporter::multistrmap ini = importer.loadIniFile(iniFile); MwIniImporter::multistrmap cfg = importer.loadCfgFile(cfgFile); importer.merge(cfg, ini); - + importer.mergeFallback(cfg, ini); + if(vm.count("game-files")) { importer.importGameFiles(cfg, ini); } std::cout << "write to: " << outputFile << std::endl; + boost::iostreams::stream file(outputFile); importer.writeToFile(file, cfg); return 0; diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 3dabc9ac8d..2342882e07 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,6 +25,7 @@ add_openmw_dir (mwinput add_openmw_dir (mwgui layouts text_input widgets race class birth review window_manager console dialogue dialogue_history window_base stats_window messagebox journalwindow charactercreation + map_window window_pinnable_base ) add_openmw_dir (mwdialogue @@ -39,7 +40,7 @@ add_openmw_dir (mwscript ) add_openmw_dir (mwsound - soundmanager openal_output mpgsnd_decoder ffmpeg_decoder + soundmanager openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder ) add_openmw_dir (mwworld @@ -54,7 +55,7 @@ add_openmw_dir (mwclass ) add_openmw_dir (mwmechanics - mechanicsmanager stat creaturestats magiceffects movement + mechanicsmanager stat creaturestats magiceffects movement actors ) # Main executable diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 38050e53b4..259733600f 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -82,12 +83,20 @@ void OMW::Engine::updateFocusReport (float duration) if (!handle.empty()) { - MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); + // the faced handle is not updated immediately, so on a cell change it might + // point to an object that doesn't exist anymore + // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case + try + { + MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); - if (!ptr.isEmpty()){ - name = MWWorld::Class::get (ptr).getName (ptr); + if (!ptr.isEmpty()){ + name = MWWorld::Class::get (ptr).getName (ptr); + } } + catch (std::runtime_error& e) + {} } if (name!=mFocusName) @@ -115,6 +124,9 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) { mEnvironment.mFrameDuration = evt.timeSinceLastFrame; + // update input + mEnvironment.mInputManager->update(); + // sound if (mUseSound) mEnvironment.mSoundManager->update (evt.timeSinceLastFrame); @@ -148,7 +160,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) // update actors std::vector > movement; - mEnvironment.mMechanicsManager->update (movement); + mEnvironment.mMechanicsManager->update (movement, mEnvironment.mFrameDuration, + mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game); if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game) mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration); @@ -313,6 +326,29 @@ void OMW::Engine::go() { boost::filesystem::create_directories(configPath); } + + // Create the settings manager and load default settings file + Settings::Manager settings; + const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg"; + const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg"; + + // prefer local + if (boost::filesystem::exists(localdefault)) + settings.loadDefault(localdefault); + else if (boost::filesystem::exists(globaldefault)) + settings.loadDefault(globaldefault); + + // load user settings if they exist, otherwise just load the default settings as user settings + const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg"; + if (boost::filesystem::exists(settingspath)) + settings.loadUser(settingspath); + else if (boost::filesystem::exists(localdefault)) + settings.loadUser(localdefault); + else if (boost::filesystem::exists(globaldefault)) + settings.loadUser(globaldefault); + + mFpsLevel = settings.getInt("fps", "HUD"); + mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()), mCfgMgr.getOgreConfigPath().string(), mCfgMgr.getLogPath().string(), @@ -322,9 +358,10 @@ void OMW::Engine::go() // to find core.xml here. //addResourcesDirectory(mResDir); - + addResourcesDirectory(mResDir / "mygui"); addResourcesDirectory(mResDir / "water"); + addResourcesDirectory(mResDir / "gbuffer"); // Create the window mOgre->createWindow("OpenMW"); @@ -333,7 +370,7 @@ void OMW::Engine::go() // Create the world mEnvironment.mWorld = new MWWorld::World (*mOgre, mFileCollections, mMaster, - mResDir, mNewGame, mEnvironment, mEncoding); + mResDir, mNewGame, mEnvironment, mEncoding, mFallbackMap); // Create window manager - this manages all the MW-specific GUI windows MWScript::registerExtensions (mExtensions); @@ -407,6 +444,9 @@ void OMW::Engine::go() // Start the main rendering loop mOgre->start(); + // Save user settings + settings.saveUser(settingspath); + std::cout << "Quitting peacefully.\n"; } @@ -420,10 +460,21 @@ void OMW::Engine::activate() if (handle.empty()) return; - MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); + // the faced handle is not updated immediately, so on a cell change it might + // point to an object that doesn't exist anymore + // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case + MWWorld::Ptr ptr; + try + { + ptr = mEnvironment.mWorld->getPtrViaHandle (handle); - if (ptr.isEmpty()) + if (ptr.isEmpty()) + return; + } + catch (std::runtime_error&) + { return; + } MWScript::InterpreterContext interpreterContext (mEnvironment, &ptr.getRefData().getLocals(), ptr); @@ -489,3 +540,8 @@ void OMW::Engine::setEncoding(const std::string& encoding) { mEncoding = encoding; } + +void OMW::Engine::setFallbackValues(std::map fallbackMap) +{ + mFallbackMap = fallbackMap; +} diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 690430784b..6eae20cc0f 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -76,6 +76,7 @@ namespace OMW bool mReportFocus; float mFocusTDiff; std::string mFocusName; + std::map mFallbackMap; MWWorld::Environment mEnvironment; Compiler::Extensions mExtensions; @@ -163,6 +164,8 @@ namespace OMW void setAnimationVerbose(bool animverbose); + void setFallbackValues(std::map map); + private: Files::ConfigurationManager& mCfgMgr; }; diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index cd1e0e26e4..df52faab14 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -54,6 +54,41 @@ inline boost::filesystem::path lexical_cast mMap; +}; + +void validate(boost::any &v, std::vector const &tokens, FallbackMap*, int) +{ + if(v.empty()) + { + v = boost::any(FallbackMap()); + } + + FallbackMap *map = boost::any_cast(&v); + + std::map::iterator mapIt; + for(std::vector::const_iterator it=tokens.begin(); it != tokens.end(); it++) + { + int sep = it->find(","); + if(sep < 1 || sep == (int)it->length()-1) +#if (BOOST_VERSION < 104200) + throw boost::program_options::validation_error("invalid value"); +#else + throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value); +#endif + + std::string key(it->substr(0,sep)); + std::string value(it->substr(sep+1)); + + if((mapIt = map->mMap.find(key)) == map->mMap.end()) + { + map->mMap.insert(std::make_pair(key,value)); + } + } +} + + /** * \brief Parses application command line and calls \ref Cfg::ConfigurationManager * to parse configuration files. @@ -92,39 +127,40 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("plugin", bpo::value()->default_value(StringsVector(), "") ->multitoken(), "plugin file(s)") - ("fps", boost::program_options::value()->implicit_value(1) - ->default_value(0), "fps counter detail (0 = off, 1 = fps counter, 2 = full detail)") - - ("anim-verbose", boost::program_options::value()->implicit_value(true) + ("anim-verbose", bpo::value()->implicit_value(true) ->default_value(false), "output animation indices files") - ("debug", boost::program_options::value()->implicit_value(true) + ("debug", bpo::value()->implicit_value(true) ->default_value(false), "debug mode") - ("nosound", boost::program_options::value()->implicit_value(true) + ("nosound", bpo::value()->implicit_value(true) ->default_value(false), "disable all sounds") - ("script-verbose", boost::program_options::value()->implicit_value(true) + ("script-verbose", bpo::value()->implicit_value(true) ->default_value(false), "verbose script output") - ("new-game", boost::program_options::value()->implicit_value(true) + ("new-game", bpo::value()->implicit_value(true) ->default_value(false), "activate char gen/new game mechanics") - ("script-all", boost::program_options::value()->implicit_value(true) + ("script-all", bpo::value()->implicit_value(true) ->default_value(false), "compile all scripts (excluding dialogue scripts) at startup") - ("fs-strict", boost::program_options::value()->implicit_value(true) + ("fs-strict", bpo::value()->implicit_value(true) ->default_value(false), "strict file system handling (no case folding)") - ( "encoding", boost::program_options::value()-> + ( "encoding", bpo::value()-> default_value("win1252"), "Character encoding used in OpenMW game messages:\n" "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1252 - Western European (Latin) alphabet, used by default") - ("report-focus", boost::program_options::value()->implicit_value(true) + ("report-focus", bpo::value()->implicit_value(true) ->default_value(false), "write name of focussed object to cout") + + ("fallback", bpo::value()->default_value(FallbackMap(), "") + ->multitoken()->composing(), "fallback values") + ; bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) @@ -225,13 +261,13 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat engine.setNewGame(variables["new-game"].as()); // other settings - engine.showFPS(variables["fps"].as()); engine.setDebugMode(variables["debug"].as()); engine.setSoundUsage(!variables["nosound"].as()); engine.setScriptsVerbosity(variables["script-verbose"].as()); engine.setCompileAll(variables["script-all"].as()); engine.setReportFocus(variables["report-focus"].as()); engine.setAnimationVerbose(variables["anim-verbose"].as()); + engine.setFallbackValues(variables["fallback"].as().mMap); return true; } diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index d27d0bc71d..90db40b5ae 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Apparatus::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Apparatus::registerSelf() { boost::shared_ptr instance (new Apparatus); diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index c0849e1fe2..861610f6cc 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 9956a56fb5..8e1f81136b 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -160,6 +160,14 @@ namespace MWClass return ESM::Skill::HeavyArmor; } + int Armor::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Armor::registerSelf() { boost::shared_ptr instance (new Armor); diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index 2b66ff8280..de5ca39835 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -40,6 +40,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 76370dc5c0..9069d94765 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -72,6 +72,14 @@ namespace MWClass return ref->base->script; } + int Book::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Book::registerSelf() { boost::shared_ptr instance (new Book); diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index ccbbfb4b2d..4738187cd6 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 2357851d75..1fbc11c631 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -123,6 +123,14 @@ namespace MWClass return -1; } + int Clothing::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Clothing::registerSelf() { boost::shared_ptr instance (new Clothing); diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 171b062461..97e09012d5 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -34,6 +34,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index cbe153ba3a..9707e79a8f 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -68,6 +68,14 @@ namespace MWClass return ref->base->script; } + int Ingredient::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Ingredient::registerSelf() { boost::shared_ptr instance (new Ingredient); diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index 9463dcf8d7..2d77176727 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 71e4775916..f67dd4cf05 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -110,6 +110,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Light::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Light::registerSelf() { boost::shared_ptr instance (new Light); diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 46a4d60ba4..bde252c289 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -34,6 +34,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 1eef0db8ba..76bc3948f6 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -81,6 +81,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Lockpick::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Lockpick::registerSelf() { boost::shared_ptr instance (new Lockpick); diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index 0c9189c548..1b56234af1 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -29,6 +29,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index def1a90a86..84099caaaf 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Miscellaneous::registerSelf() { boost::shared_ptr instance (new Miscellaneous); diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index b07964f990..fc002280cf 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index ed1733e2d2..642211df3c 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Potion::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Potion::registerSelf() { boost::shared_ptr instance (new Potion); diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index be9e713fba..7d30179376 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 8013e2e80f..923c29ee69 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -80,6 +80,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Probe::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Probe::registerSelf() { boost::shared_ptr instance (new Probe); diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index 1507d65aab..232b523645 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -29,6 +29,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index d49979861b..d6433f5df5 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Repair::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Repair::registerSelf() { boost::shared_ptr instance (new Repair); diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 17b606f4cb..0a9d9c2535 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index e36e9202fa..7790e6a80b 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -139,6 +139,14 @@ namespace MWClass return -1; } + int Weapon::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Weapon::registerSelf() { boost::shared_ptr instance (new Weapon); diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index f863c0bfe2..505c45645f 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -40,6 +40,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 50549f4a55..b06605cc28 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -528,6 +528,13 @@ namespace MWDialogue mChoice = -1; mIsInChoice = false; mCompilerContext.setExtensions (&extensions); + mDialogueMap.clear(); + actorKnownTopics.clear(); + ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; + for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) + { + mDialogueMap[it->first] = it->second; + } } void DialogueManager::addTopic(std::string topic) @@ -563,13 +570,7 @@ namespace MWDialogue mActor = actor; - mDialogueMap.clear(); actorKnownTopics.clear(); - ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; - for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) - { - mDialogueMap[it->first] = it->second; - } //initialise the GUI mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue); @@ -582,6 +583,7 @@ namespace MWDialogue //greeting bool greetingFound = false; //ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; + ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) { ESM::Dialogue ndialogue = it->second; diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index de74214eef..6d8aa901b5 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -31,6 +31,11 @@ HUD::HUD(int width, int height, int fpsLevel) , fpscounter(NULL) , trianglecounter(NULL) , batchcounter(NULL) + , hmsBaseLeft(0) + , weapBoxBaseLeft(0) + , spellBoxBaseLeft(0) + , effectBoxBaseRight(0) + , minimapBoxBaseRight(0) { setCoord(0,0, width, height); @@ -38,16 +43,25 @@ HUD::HUD(int width, int height, int fpsLevel) getWidget(health, "Health"); getWidget(magicka, "Magicka"); getWidget(stamina, "Stamina"); + hmsBaseLeft = health->getLeft(); // Item and spell images and status bars + getWidget(weapBox, "WeapBox"); getWidget(weapImage, "WeapImage"); getWidget(weapStatus, "WeapStatus"); + weapBoxBaseLeft = weapBox->getLeft(); + + getWidget(spellBox, "SpellBox"); getWidget(spellImage, "SpellImage"); getWidget(spellStatus, "SpellStatus"); + spellBoxBaseLeft = spellBox->getLeft(); getWidget(effectBox, "EffectBox"); getWidget(effect1, "Effect1"); + effectBoxBaseRight = effectBox->getRight(); + getWidget(minimapBox, "MiniMapBox"); + minimapBoxBaseRight = minimapBox->getRight(); getWidget(minimap, "MiniMap"); getWidget(compass, "Compass"); @@ -163,15 +177,21 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& v void HUD::setPlayerDir(const float x, const float y) { + if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return; + MyGUI::ISubWidget* main = compass->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); float angle = std::atan2(x,y); rotatingSubskin->setAngle(angle); + mLastPositionX = x; + mLastPositionY = y; } void HUD::setPlayerPos(const float x, const float y) { + if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return; + MyGUI::IntSize size = minimap->getCanvasSize(); MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); MyGUI::IntCoord viewsize = minimap->getCoord(); @@ -179,109 +199,54 @@ void HUD::setPlayerPos(const float x, const float y) minimap->setViewOffset(pos); compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); + + mLastDirectionX = x; + mLastDirectionY = y; } -MapWindow::MapWindow() - : Layout("openmw_map_window_layout.xml") - , mGlobal(false) - , mVisible(false) +void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible) { - setCoord(500,0,320,300); - setText("WorldButton", "World"); - setImage("Compass", "textures\\compass.dds"); + int weapDx = 0, spellDx = 0; + if (!hmsVisible) + spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft; - // Obviously you should override this later on - setCellName("No Cell Loaded"); + if (!weapVisible) + spellDx -= spellBoxBaseLeft - weapBoxBaseLeft; - getWidget(mLocalMap, "LocalMap"); - getWidget(mGlobalMap, "GlobalMap"); - getWidget(mPlayerArrow, "Compass"); - - getWidget(mButton, "WorldButton"); - mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); - - MyGUI::Button* eventbox; - getWidget(eventbox, "EventBox"); - eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); - eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); - - LocalMapBase::init(mLocalMap, this); + health->setVisible(hmsVisible); + stamina->setVisible(hmsVisible); + magicka->setVisible(hmsVisible); + weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop()); + weapBox->setVisible(weapVisible); + spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop()); + spellBox->setVisible(spellVisible); } -void MapWindow::setVisible(bool b) +void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible) { - mMainWidget->setVisible(b); - if (b) - mVisible = true; - else - mVisible = false; -} + // effect box can have variable width -> variable left coordinate + int effectsDx = 0; + if (!minimapBoxVisible) + effectsDx = minimapBoxBaseRight - effectBoxBaseRight; -void MapWindow::setCellName(const std::string& cellName) -{ - static_cast(mMainWidget)->setCaption(cellName); - adjustWindowCaption(); -} - -void MapWindow::setPlayerPos(const float x, const float y) -{ - if (mGlobal || mVisible) return; - MyGUI::IntSize size = mLocalMap->getCanvasSize(); - MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); - MyGUI::IntCoord viewsize = mLocalMap->getCoord(); - MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); - mLocalMap->setViewOffset(pos); - - mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); -} - -void MapWindow::setPlayerDir(const float x, const float y) -{ - if (!mVisible) return; - MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); - MyGUI::RotatingSkin* rotatingSubskin = main->castType(); - rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); - float angle = std::atan2(x,y); - rotatingSubskin->setAngle(angle); -} - -void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) -{ - if (_id!=MyGUI::MouseButton::Left) return; - if (!mGlobal) - mLastDragPos = MyGUI::IntPoint(_left, _top); -} - -void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) -{ - if (_id!=MyGUI::MouseButton::Left) return; - - if (!mGlobal) - { - MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; - mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); - - mLastDragPos = MyGUI::IntPoint(_left, _top); - } -} - -void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) -{ - mGlobal = !mGlobal; - mGlobalMap->setVisible(mGlobal); - mLocalMap->setVisible(!mGlobal); - - mButton->setCaption( mGlobal ? "Local" : "World" ); + minimapBox->setVisible(minimapBoxVisible); + effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop()); + effectBox->setVisible(effectBoxVisible); } LocalMapBase::LocalMapBase() : mCurX(0) , mCurY(0) , mInterior(false) + , mFogOfWar(true) , mLocalMap(NULL) , mPrefix() , mChanged(true) , mLayout(NULL) + , mLastPositionX(0.0f) + , mLastPositionY(0.0f) + , mLastDirectionX(0.0f) + , mLastDirectionY(0.0f) { } @@ -297,6 +262,32 @@ void LocalMapBase::setCellPrefix(const std::string& prefix) mChanged = true; } +void LocalMapBase::toggleFogOfWar() +{ + mFogOfWar = !mFogOfWar; + applyFogOfWar(); +} + +void LocalMapBase::applyFogOfWar() +{ + for (int mx=0; mx<3; ++mx) + { + for (int my=0; my<3; ++my) + { + std::string name = "Map_" + boost::lexical_cast(mx) + "_" + + boost::lexical_cast(my); + std::string image = mPrefix+"_"+ boost::lexical_cast(mCurX + (mx-1)) + "_" + + boost::lexical_cast(mCurY + (mInterior ? (my-1) : -1*(my-1))); + MyGUI::ImageBox* fog; + mLayout->getWidget(fog, name+"_fog"); + fog->setImageTexture(mFogOfWar ? + ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog" + : "black.png" ) + : ""); + } + } +} + void LocalMapBase::setActiveCell(const int x, const int y, bool interior) { if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell @@ -312,23 +303,17 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior) MyGUI::ImageBox* box; mLayout->getWidget(box, name); - MyGUI::ImageBox* fog; - mLayout->getWidget(fog, name+"_fog"); if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) box->setImageTexture(image); else box->setImageTexture("black.png"); - - if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) - fog->setImageTexture(image+"_fog"); - else - fog->setImageTexture("black.png"); } } mInterior = interior; mCurX = x; mCurY = y; mChanged = false; + applyFogOfWar(); } diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 614479ccce..0614708cf1 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -40,14 +40,24 @@ namespace MWGui void setCellPrefix(const std::string& prefix); void setActiveCell(const int x, const int y, bool interior=false); + void toggleFogOfWar(); + protected: int mCurX, mCurY; bool mInterior; MyGUI::ScrollView* mLocalMap; std::string mPrefix; bool mChanged; + bool mFogOfWar; + + void applyFogOfWar(); OEngine::GUI::Layout* mLayout; + + float mLastPositionX; + float mLastPositionY; + float mLastDirectionX; + float mLastDirectionY; }; class HUD : public OEngine::GUI::Layout, public LocalMapBase @@ -66,11 +76,14 @@ namespace MWGui void setBatchCount(size_t count); void setPlayerDir(const float x, const float y); void setPlayerPos(const float x, const float y); + void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible); + void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); MyGUI::ProgressPtr health, magicka, stamina; + MyGUI::Widget *weapBox, *spellBox; MyGUI::ImageBox *weapImage, *spellImage; MyGUI::ProgressPtr weapStatus, spellStatus; - MyGUI::WidgetPtr effectBox; + MyGUI::Widget *effectBox, *minimapBox; MyGUI::ImageBox* effect1; MyGUI::ScrollView* minimap; MyGUI::ImageBox* compass; @@ -80,30 +93,12 @@ namespace MWGui MyGUI::TextBox* fpscounter; MyGUI::TextBox* trianglecounter; MyGUI::TextBox* batchcounter; - }; - class MapWindow : public OEngine::GUI::Layout, public LocalMapBase - { - public: - MapWindow(); - virtual ~MapWindow(){} - - void setVisible(bool b); - void setPlayerPos(const float x, const float y); - void setPlayerDir(const float x, const float y); - void setCellName(const std::string& cellName); - private: - void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); - void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); - void onWorldButtonClicked(MyGUI::Widget* _sender); - - MyGUI::ScrollView* mGlobalMap; - MyGUI::ImageBox* mPlayerArrow; - MyGUI::Button* mButton; - MyGUI::IntPoint mLastDragPos; - bool mVisible; - bool mGlobal; + // bottom left elements + int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft; + // bottom right elements + int minimapBoxBaseRight, effectBoxBaseRight; }; class MainMenu : public OEngine::GUI::Layout diff --git a/apps/openmw/mwgui/map_window.cpp b/apps/openmw/mwgui/map_window.cpp new file mode 100644 index 0000000000..0e9d57c3c2 --- /dev/null +++ b/apps/openmw/mwgui/map_window.cpp @@ -0,0 +1,106 @@ +#include "map_window.hpp" +#include "window_manager.hpp" +/* +#include "../mwmechanics/mechanicsmanager.hpp" + +#include +#include +#include + +#undef min +#undef max +*/ +using namespace MWGui; + +MapWindow::MapWindow(WindowManager& parWindowManager) : + MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager), + mGlobal(false) +{ + setCoord(500,0,320,300); + setText("WorldButton", "World"); + setImage("Compass", "textures\\compass.dds"); + + // Obviously you should override this later on + setCellName("No Cell Loaded"); + + getWidget(mLocalMap, "LocalMap"); + getWidget(mGlobalMap, "GlobalMap"); + getWidget(mPlayerArrow, "Compass"); + + getWidget(mButton, "WorldButton"); + mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); + + MyGUI::Button* eventbox; + getWidget(eventbox, "EventBox"); + eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); + eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); + + LocalMapBase::init(mLocalMap, this); +} + +void MapWindow::setCellName(const std::string& cellName) +{ + static_cast(mMainWidget)->setCaption(cellName); + adjustWindowCaption(); +} + +void MapWindow::setPlayerPos(const float x, const float y) +{ + if (mGlobal || !mVisible || (x == mLastPositionX && y == mLastPositionY)) return; + MyGUI::IntSize size = mLocalMap->getCanvasSize(); + MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); + MyGUI::IntCoord viewsize = mLocalMap->getCoord(); + MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); + mLocalMap->setViewOffset(pos); + + mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); + mLastPositionX = x; + mLastPositionY = y; +} + +void MapWindow::setPlayerDir(const float x, const float y) +{ + if (!mVisible || (x == mLastDirectionX && y == mLastDirectionY)) return; + MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); + MyGUI::RotatingSkin* rotatingSubskin = main->castType(); + rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); + float angle = std::atan2(x,y); + rotatingSubskin->setAngle(angle); + + mLastDirectionX = x; + mLastDirectionY = y; +} + +void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) +{ + if (_id!=MyGUI::MouseButton::Left) return; + if (!mGlobal) + mLastDragPos = MyGUI::IntPoint(_left, _top); +} + +void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) +{ + if (_id!=MyGUI::MouseButton::Left) return; + + if (!mGlobal) + { + MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; + mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); + + mLastDragPos = MyGUI::IntPoint(_left, _top); + } +} + +void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) +{ + mGlobal = !mGlobal; + mGlobalMap->setVisible(mGlobal); + mLocalMap->setVisible(!mGlobal); + + mButton->setCaption( mGlobal ? "Local" : "World" ); +} + +void MapWindow::onPinToggled() +{ + mWindowManager.setMinimapVisibility(!mPinned); +} diff --git a/apps/openmw/mwgui/map_window.hpp b/apps/openmw/mwgui/map_window.hpp new file mode 100644 index 0000000000..d14221a408 --- /dev/null +++ b/apps/openmw/mwgui/map_window.hpp @@ -0,0 +1,34 @@ +#ifndef MWGUI_MAPWINDOW_H +#define MWGUI_MAPWINDOW_H + +#include "layouts.hpp" +#include "window_pinnable_base.hpp" + +namespace MWGui +{ + class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase + { + public: + MapWindow(WindowManager& parWindowManager); + virtual ~MapWindow(){} + + void setPlayerPos(const float x, const float y); + void setPlayerDir(const float x, const float y); + void setCellName(const std::string& cellName); + + private: + void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onWorldButtonClicked(MyGUI::Widget* _sender); + + MyGUI::ScrollView* mGlobalMap; + MyGUI::ImageBox* mPlayerArrow; + MyGUI::Button* mButton; + MyGUI::IntPoint mLastDragPos; + bool mGlobal; + + protected: + virtual void onPinToggled(); + }; +} +#endif diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 12b0dcc793..675e5141fa 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -12,7 +12,7 @@ using namespace MWGui; const int StatsWindow::lineHeight = 18; StatsWindow::StatsWindow (WindowManager& parWindowManager) - : WindowBase("openmw_stats_window_layout.xml", parWindowManager) + : WindowPinnableBase("openmw_stats_window_layout.xml", parWindowManager) , skillAreaWidget(NULL) , skillClientWidget(NULL) , skillScrollerWidget(NULL) @@ -381,3 +381,8 @@ void StatsWindow::updateScroller() skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); } + +void StatsWindow::onPinToggled() +{ + mWindowManager.setHMSVisibility(!mPinned); +} diff --git a/apps/openmw/mwgui/stats_window.hpp b/apps/openmw/mwgui/stats_window.hpp index 2ff170f571..f2731e545c 100644 --- a/apps/openmw/mwgui/stats_window.hpp +++ b/apps/openmw/mwgui/stats_window.hpp @@ -9,13 +9,13 @@ #include #include "../mwmechanics/stat.hpp" -#include "window_base.hpp" +#include "window_pinnable_base.hpp" namespace MWGui { class WindowManager; - class StatsWindow : public WindowBase + class StatsWindow : public WindowPinnableBase { public: typedef std::pair Faction; @@ -74,6 +74,9 @@ namespace MWGui std::string birthSignId; int reputation, bounty; std::vector skillWidgets; //< Skills and other information + + protected: + virtual void onPinToggled(); }; } #endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 49b6e644d3..13b6fab310 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -4,6 +4,7 @@ #include "review.hpp" #include "dialogue.hpp" #include "dialogue_history.hpp" +#include "map_window.hpp" #include "stats_window.hpp" #include "messagebox.hpp" @@ -71,7 +72,7 @@ WindowManager::WindowManager(MWWorld::Environment& environment, hud = new HUD(w,h, showFPSLevel); menu = new MainMenu(w,h); - map = new MapWindow(); + map = new MapWindow(*this); stats = new StatsWindow(*this); console = new Console(w,h, environment, extensions); mJournal = new JournalWindow(*this); @@ -455,3 +456,19 @@ void WindowManager::setPlayerDir(const float x, const float y) map->setPlayerDir(x,y); hud->setPlayerDir(x,y); } + +void WindowManager::setHMSVisibility(bool visible) +{ + hud->setBottomLeftVisibility(visible, hud->weapBox->getVisible(), hud->spellBox->getVisible()); +} + +void WindowManager::setMinimapVisibility(bool visible) +{ + hud->setBottomRightVisibility(hud->effectBox->getVisible(), visible); +} + +void WindowManager::toggleFogOfWar() +{ + map->toggleFogOfWar(); + hud->toggleFogOfWar(); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 582f438e8f..f1db11731b 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -156,10 +156,17 @@ namespace MWGui void changeCell(MWWorld::Ptr::CellStore* cell); ///< change the active cell void setPlayerPos(const float x, const float y); ///< set player position in map space void setPlayerDir(const float x, const float y); ///< set player view direction in map space + + void toggleFogOfWar(); void setInteriorMapTexture(const int x, const int y); ///< set the index of the map texture that should be used (for interiors) + // sets the visibility of the hud health/magicka/stamina bars + void setHMSVisibility(bool visible); + // sets the visibility of the hud minimap + void setMinimapVisibility(bool visible); + template void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr. void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted. diff --git a/apps/openmw/mwgui/window_pinnable_base.cpp b/apps/openmw/mwgui/window_pinnable_base.cpp new file mode 100644 index 0000000000..ecdf311c6e --- /dev/null +++ b/apps/openmw/mwgui/window_pinnable_base.cpp @@ -0,0 +1,33 @@ +#include "window_pinnable_base.hpp" +#include "window_manager.hpp" + +using namespace MWGui; + +WindowPinnableBase::WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager) + : WindowBase(parLayout, parWindowManager), mPinned(false), mVisible(false) +{ + MyGUI::WindowPtr t = static_cast(mMainWidget); + t->eventWindowButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onWindowButtonPressed); +} + +void WindowPinnableBase::setVisible(bool b) +{ + // Pinned windows can not be hidden + if (mPinned && !b) + return; + + WindowBase::setVisible(b); + mVisible = b; +} + +void WindowPinnableBase::onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName) +{ + if ("PinToggle" == eventName) + { + mPinned = !mPinned; + onPinToggled(); + } + + eventDone(this); +} + diff --git a/apps/openmw/mwgui/window_pinnable_base.hpp b/apps/openmw/mwgui/window_pinnable_base.hpp new file mode 100644 index 0000000000..8ef38c3867 --- /dev/null +++ b/apps/openmw/mwgui/window_pinnable_base.hpp @@ -0,0 +1,28 @@ +#ifndef MWGUI_WINDOW_PINNABLE_BASE_H +#define MWGUI_WINDOW_PINNABLE_BASE_H + +#include "window_base.hpp" + +namespace MWGui +{ + class WindowManager; + + class WindowPinnableBase: public WindowBase + { + public: + WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager); + void setVisible(bool b); + + private: + void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName); + + protected: + virtual void onPinToggled() = 0; + + bool mPinned; + bool mVisible; + }; +} + +#endif + diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 88534dddae..3721d10431 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -70,7 +70,7 @@ namespace MWInput }; // Class that handles all input and key bindings for OpenMW - class InputImpl : public Ogre::FrameListener + class InputImpl { OEngine::Input::DispatcherPtr disp; OEngine::Render::OgreRenderer &ogre; @@ -200,8 +200,6 @@ namespace MWInput // Add the exit listener ogre.getRoot()->addFrameListener(&exit); - // Add ourselves as a frame listener to catch movement keys - ogre.getRoot()->addFrameListener(this); // Set up the mouse handler and tell it about the player camera mouse = MouseLookEventPtr(new MouseLookEvent(player.getRenderer()->getCamera())); @@ -262,7 +260,7 @@ namespace MWInput } //NOTE: Used to check for movement keys - bool frameRenderingQueued (const Ogre::FrameEvent &evt) + void update () { // Tell OIS to handle all input events input.capture(); @@ -276,7 +274,7 @@ namespace MWInput windows.update(); // Disable movement in Gui mode - if (windows.isGuiMode()) return true; + if (windows.isGuiMode()) return; // Configure player movement according to keyboard input. Actual movement will // be done in the physics system. @@ -305,8 +303,6 @@ namespace MWInput } else player.setForwardBackward (0); - - return true; } // Switch between gui modes. Besides controlling the Gui windows @@ -358,4 +354,9 @@ namespace MWInput { impl->setGuiMode(mode); } + + void MWInputManager::update() + { + impl->update(); + } } diff --git a/apps/openmw/mwinput/inputmanager.hpp b/apps/openmw/mwinput/inputmanager.hpp index 6b8034c8b4..721c77d9fd 100644 --- a/apps/openmw/mwinput/inputmanager.hpp +++ b/apps/openmw/mwinput/inputmanager.hpp @@ -48,6 +48,8 @@ namespace MWInput OMW::Engine& engine); ~MWInputManager(); + void update(); + void setGuiMode(MWGui::GuiMode mode); }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp new file mode 100644 index 0000000000..7d9f748d4a --- /dev/null +++ b/apps/openmw/mwmechanics/actors.cpp @@ -0,0 +1,77 @@ + +#include "actors.hpp" + +#include + +#include + +#include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" + +namespace MWMechanics +{ + void Actors::updateActor (const MWWorld::Ptr& ptr, float duration) + { + + } + + void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) + { + if (!paused && ptr.getRefData().getHandle()!="player") + MWWorld::Class::get (ptr).getInventoryStore (ptr).autoEquip ( + MWWorld::Class::get (ptr).getNpcStats (ptr), mEnvironment); + } + + Actors::Actors (MWWorld::Environment& environment) : mEnvironment (environment), mDuration (0) {} + + void Actors::addActor (const MWWorld::Ptr& ptr) + { + mActors.insert (ptr); + } + + void Actors::removeActor (const MWWorld::Ptr& ptr) + { + mActors.erase (ptr); + } + + void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore) + { + std::set::iterator iter = mActors.begin(); + + while (iter!=mActors.end()) + if (iter->getCell()==cellStore) + { + mActors.erase (iter++); + } + else + ++iter; + } + + void Actors::update (std::vector >& movement, float duration, + bool paused) + { + mDuration += duration; + + if (mDuration>=0.25) + { + for (std::set::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter) + { + updateActor (*iter, mDuration); + + if (iter->getTypeName()==typeid (ESM::NPC).name()) + updateNpc (*iter, mDuration, paused); + } + + mDuration = 0; + } + + for (std::set::iterator iter (mActors.begin()); iter!=mActors.end(); + ++iter) + { + Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter); + + if (vector!=Ogre::Vector3::ZERO) + movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector)); + } + } +} diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp new file mode 100644 index 0000000000..7ff33b63bd --- /dev/null +++ b/apps/openmw/mwmechanics/actors.hpp @@ -0,0 +1,51 @@ +#ifndef GAME_MWMECHANICS_ACTORS_H +#define GAME_MWMECHANICS_ACTORS_H + +#include +#include +#include + +#include "../mwworld/ptr.hpp" + +namespace Ogre +{ + class Vector3; +} + +namespace MWWorld +{ + class Environment; +} + +namespace MWMechanics +{ + class Actors + { + MWWorld::Environment& mEnvironment; + std::set mActors; + float mDuration; + + void updateActor (const MWWorld::Ptr& ptr, float duration); + + void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused); + + public: + + Actors (MWWorld::Environment& environment); + + void addActor (const MWWorld::Ptr& ptr); + ///< Register an actor for stats management + + void removeActor (const MWWorld::Ptr& ptr); + ///< Deregister an actor for stats management + + void dropActors (const MWWorld::Ptr::CellStore *cellStore); + ///< Deregister all actors in the given cell. + + void update (std::vector >& movement, + float duration, bool paused); + ///< Update actor stats and store desired velocity vectors in \a movement + }; +} + +#endif diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 7ed81f7850..3c93857ef9 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -222,14 +222,14 @@ namespace MWMechanics MechanicsManager::MechanicsManager (MWWorld::Environment& environment) : mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false), - mRaceSelected (false) + mRaceSelected (false), mActors (environment) { buildPlayer(); } void MechanicsManager::addActor (const MWWorld::Ptr& ptr) { - mActors.insert (ptr); + mActors.addActor (ptr); } void MechanicsManager::removeActor (const MWWorld::Ptr& ptr) @@ -237,7 +237,7 @@ namespace MWMechanics if (ptr==mWatched) mWatched = MWWorld::Ptr(); - mActors.erase (ptr); + mActors.removeActor (ptr); } void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore) @@ -245,16 +245,7 @@ namespace MWMechanics if (!mWatched.isEmpty() && mWatched.getCell()==cellStore) mWatched = MWWorld::Ptr(); - std::set::iterator iter = mActors.begin(); - - while (iter!=mActors.end()) - if (iter->getCell()==cellStore) - { - //std::cout << "Erasing an actor"; - mActors.erase (iter++); - } - else - ++iter; + mActors.dropActors (cellStore); } void MechanicsManager::watchActor (const MWWorld::Ptr& ptr) @@ -262,7 +253,8 @@ namespace MWMechanics mWatched = ptr; } - void MechanicsManager::update (std::vector >& movement) + void MechanicsManager::update (std::vector >& movement, + float duration, bool paused) { if (!mWatched.isEmpty()) { @@ -345,14 +337,7 @@ namespace MWMechanics mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills); } - for (std::set::iterator iter (mActors.begin()); iter!=mActors.end(); - ++iter) - { - Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter); - - if (vector!=Ogre::Vector3::ZERO) - movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector)); - } + mActors.update (movement, duration, paused); } void MechanicsManager::setPlayerName (const std::string& name) diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index 2e2192638f..a7defe178a 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -1,7 +1,6 @@ #ifndef GAME_MWMECHANICS_MECHANICSMANAGER_H #define GAME_MWMECHANICS_MECHANICSMANAGER_H -#include #include #include @@ -9,6 +8,7 @@ #include "creaturestats.hpp" #include "npcstats.hpp" +#include "actors.hpp" namespace Ogre { @@ -25,13 +25,13 @@ namespace MWMechanics class MechanicsManager { MWWorld::Environment& mEnvironment; - std::set mActors; MWWorld::Ptr mWatched; CreatureStats mWatchedCreature; NpcStats mWatchedNpc; bool mUpdatePlayer; bool mClassSelected; bool mRaceSelected; + Actors mActors; void buildPlayer(); ///< build player according to stored class/race/birthsign information. Will @@ -60,8 +60,12 @@ namespace MWMechanics ///< On each update look for changes in a previously registered actor and update the /// GUI accordingly. - void update (std::vector >& movement); + void update (std::vector >& movement, float duration, + bool paused); ///< Update actor stats and store desired velocity vectors in \a movement + /// + /// \param paused In game type does not currently advance (this usually means some GUI + /// component is up). void setPlayerName (const std::string& name); ///< Set player name. diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 4de6453aa6..e0eb5ccc20 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -1,4 +1,5 @@ #include "creatureanimation.hpp" +#include "renderconst.hpp" #include "../mwworld/world.hpp" @@ -20,6 +21,28 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme std::string meshNumbered = mesh + getUniqueID(mesh) + ">|"; NifOgre::NIFLoader::load(meshNumbered); base = mRend.getScene()->createEntity(meshNumbered); + base->setVisibilityFlags(RV_Actors); + + bool transparent = false; + for (unsigned int i=0; igetNumSubEntities(); ++i) + { + Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial(); + Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); + while (techIt.hasMoreElements()) + { + Ogre::Technique* tech = techIt.getNext(); + Ogre::Technique::PassIterator passIt = tech->getPassIterator(); + while (passIt.hasMoreElements()) + { + Ogre::Pass* pass = passIt.getNext(); + + if (pass->getDepthWriteEnabled() == false) + transparent = true; + } + } + } + base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); + std::string meshZero = mesh + "0000>|"; if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){ diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 4221852730..d426721795 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -2,33 +2,283 @@ #include -#include "OgreRoot.h" -#include "OgreRenderWindow.h" -#include "OgreSceneManager.h" -#include "OgreViewport.h" -#include "OgreCamera.h" -#include "OgreTextureManager.h" +#include +#include +#include +#include #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone +#include "../mwworld/environment.hpp" #include "../mwworld/ptr.hpp" #include +#include #include "player.hpp" -using namespace MWRender; using namespace Ogre; -Debugging::Debugging(OEngine::Physic::PhysicEngine* engine){ - eng = engine; +namespace MWRender +{ + +static const std::string PATHGRID_POINT_MATERIAL = "pathgridPointMaterial"; +static const std::string PATHGRID_LINE_MATERIAL = "pathgridLineMaterial"; +static const std::string DEBUGGING_GROUP = "debugging"; +static const int POINT_MESH_BASE = 35; + +void Debugging::createGridMaterials() +{ + if (mGridMatsCreated) return; + + if (MaterialManager::getSingleton().getByName(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP).isNull()) + { + MaterialPtr lineMatPtr = MaterialManager::getSingleton().create(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP); + lineMatPtr->setReceiveShadows(false); + lineMatPtr->getTechnique(0)->setLightingEnabled(true); + lineMatPtr->getTechnique(0)->getPass(0)->setDiffuse(1,1,0,0); + lineMatPtr->getTechnique(0)->getPass(0)->setAmbient(1,1,0); + lineMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,1,0); + } + + if (MaterialManager::getSingleton().getByName(PATHGRID_POINT_MATERIAL, DEBUGGING_GROUP).isNull()) + { + MaterialPtr pointMatPtr = MaterialManager::getSingleton().create(PATHGRID_POINT_MATERIAL, DEBUGGING_GROUP); + pointMatPtr->setReceiveShadows(false); + pointMatPtr->getTechnique(0)->setLightingEnabled(true); + pointMatPtr->getTechnique(0)->getPass(0)->setDiffuse(1,0,0,0); + pointMatPtr->getTechnique(0)->getPass(0)->setAmbient(1,0,0); + pointMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,0,0); + } + mGridMatsCreated = true; +} + +void Debugging::destroyGridMaterials() +{ + if (mGridMatsCreated) + { + MaterialManager::getSingleton().remove(PATHGRID_POINT_MATERIAL); + MaterialManager::getSingleton().remove(PATHGRID_LINE_MATERIAL); + mGridMatsCreated = false; + } +} + +ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid) +{ + ManualObject *result = mSceneMgr->createManualObject(); + + result->begin(PATHGRID_LINE_MATERIAL, RenderOperation::OT_LINE_LIST); + for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->edges.begin(); + it != pathgrid->edges.end(); + it++) + { + const ESM::Pathgrid::Edge &edge = *it; + const ESM::Pathgrid::Point &p1 = pathgrid->points[edge.v0], &p2 = pathgrid->points[edge.v1]; + Vector3 direction = (Vector3(p2.x, p2.y, p2.z) - Vector3(p1.x, p1.y, p1.z)); + Vector3 lineDisplacement = direction.crossProduct(Vector3::UNIT_Z).normalisedCopy(); + lineDisplacement = lineDisplacement * POINT_MESH_BASE + + Vector3(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape + result->position(Vector3(p1.x, p1.y, p1.z) + lineDisplacement); + result->position(Vector3(p2.x, p2.y, p2.z) + lineDisplacement); + } + result->end(); + + return result; +} + +ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid) +{ + ManualObject *result = mSceneMgr->createManualObject(); + const float height = POINT_MESH_BASE * sqrtf(2); + + result->begin(PATHGRID_POINT_MATERIAL, RenderOperation::OT_TRIANGLE_STRIP); + + bool first = true; + uint32 startIndex = 0; + for(ESM::Pathgrid::PointList::const_iterator it = pathgrid->points.begin(); + it != pathgrid->points.end(); + it++, startIndex += 6) + { + Vector3 pointPos(it->x, it->y, it->z); + + if (!first) + { + // degenerate triangle from previous octahedron + result->index(startIndex - 4); // 2nd point of previous octahedron + result->index(startIndex); // start point of current octahedron + } + + result->position(pointPos + Vector3(0, 0, height)); // 0 + result->position(pointPos + Vector3(-POINT_MESH_BASE, -POINT_MESH_BASE, 0)); // 1 + result->position(pointPos + Vector3(POINT_MESH_BASE, -POINT_MESH_BASE, 0)); // 2 + result->position(pointPos + Vector3(POINT_MESH_BASE, POINT_MESH_BASE, 0)); // 3 + result->position(pointPos + Vector3(-POINT_MESH_BASE, POINT_MESH_BASE, 0)); // 4 + result->position(pointPos + Vector3(0, 0, -height)); // 5 + + result->index(startIndex + 0); + result->index(startIndex + 1); + result->index(startIndex + 2); + result->index(startIndex + 5); + result->index(startIndex + 3); + result->index(startIndex + 4); + // degenerates + result->index(startIndex + 4); + result->index(startIndex + 5); + result->index(startIndex + 5); + // end degenerates + result->index(startIndex + 1); + result->index(startIndex + 4); + result->index(startIndex + 0); + result->index(startIndex + 3); + result->index(startIndex + 2); + + first = false; + } + + result->end(); + + return result; +} + +Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) : + mMwRoot(mwRoot), mEnvironment(env), mEngine(engine), + mSceneMgr(mwRoot->getCreator()), + mPathgridEnabled(false), + mInteriorPathgridNode(NULL), mPathGridRoot(NULL), + mGridMatsCreated(false) +{ + ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP); +} + +Debugging::~Debugging() +{ + if (mPathgridEnabled) + { + togglePathgrid(); + } + + ResourceGroupManager::getSingleton().destroyResourceGroup(DEBUGGING_GROUP); } bool Debugging::toggleRenderMode (int mode){ - switch (mode) + switch (mode) { case MWWorld::World::Render_CollisionDebug: - return eng->toggleDebugRendering(); + + return mEngine->toggleDebugRendering(); + + case MWWorld::World::Render_Pathgrid: + togglePathgrid(); + return mPathgridEnabled; } return false; } + +void Debugging::cellAdded(MWWorld::Ptr::CellStore *store) +{ + mActiveCells.push_back(store); + if (mPathgridEnabled) + enableCellPathgrid(store); +} + +void Debugging::cellRemoved(MWWorld::Ptr::CellStore *store) +{ + mActiveCells.erase(std::remove(mActiveCells.begin(), mActiveCells.end(), store), mActiveCells.end()); + if (mPathgridEnabled) + disableCellPathgrid(store); +} + +void Debugging::togglePathgrid() +{ + mPathgridEnabled = !mPathgridEnabled; + if (mPathgridEnabled) + { + createGridMaterials(); + + // add path grid meshes to already loaded cells + mPathGridRoot = mMwRoot->createChildSceneNode(); + for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) + { + enableCellPathgrid(*it); + } + } + else + { + // remove path grid meshes from already loaded cells + for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) + { + disableCellPathgrid(*it); + } + mPathGridRoot->removeAndDestroyAllChildren(); + mSceneMgr->destroySceneNode(mPathGridRoot); + mPathGridRoot = NULL; + destroyGridMaterials(); + } +} + +void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store) +{ + ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell); + if (!pathgrid) return; + + Vector3 cellPathGridPos(0, 0, 0); + if (store->cell->isExterior()) + { + cellPathGridPos.x = store->cell->data.gridX * ESM::Land::REAL_SIZE; + cellPathGridPos.y = store->cell->data.gridY * ESM::Land::REAL_SIZE; + } + SceneNode *cellPathGrid = mPathGridRoot->createChildSceneNode(cellPathGridPos); + cellPathGrid->attachObject(createPathgridLines(pathgrid)); + cellPathGrid->attachObject(createPathgridPoints(pathgrid)); + + if (store->cell->isExterior()) + { + mExteriorPathgridNodes[std::make_pair(store->cell->data.gridX, store->cell->data.gridY)] = cellPathGrid; + } + else + { + assert(mInteriorPathgridNode == NULL); + mInteriorPathgridNode = cellPathGrid; + } +} + +void Debugging::disableCellPathgrid(MWWorld::Ptr::CellStore *store) +{ + if (store->cell->isExterior()) + { + ExteriorPathgridNodes::iterator it = + mExteriorPathgridNodes.find(std::make_pair(store->cell->data.gridX, store->cell->data.gridY)); + if (it != mExteriorPathgridNodes.end()) + { + destroyCellPathgridNode(it->second); + mExteriorPathgridNodes.erase(it); + } + } + else + { + if (mInteriorPathgridNode) + { + destroyCellPathgridNode(mInteriorPathgridNode); + mInteriorPathgridNode = NULL; + } + } +} + +void Debugging::destroyCellPathgridNode(SceneNode *node) +{ + mPathGridRoot->removeChild(node); + destroyAttachedObjects(node); + mSceneMgr->destroySceneNode(node); +} + +void Debugging::destroyAttachedObjects(SceneNode *node) +{ + SceneNode::ObjectIterator objIt = node->getAttachedObjectIterator(); + while (objIt.hasMoreElements()) + { + MovableObject *mesh = static_cast(objIt.getNext()); + mSceneMgr->destroyMovableObject(mesh); + } +} + +} diff --git a/apps/openmw/mwrender/debugging.hpp b/apps/openmw/mwrender/debugging.hpp index b48cfaee2a..ebf3884dcc 100644 --- a/apps/openmw/mwrender/debugging.hpp +++ b/apps/openmw/mwrender/debugging.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "../mwworld/ptr.hpp" #include #include @@ -22,20 +23,58 @@ namespace Ogre namespace MWWorld { class World; + class Environment; } namespace MWRender { class Player; - class Debugging{ - OEngine::Physic::PhysicEngine* eng; + class Debugging + { + OEngine::Physic::PhysicEngine* mEngine; + Ogre::SceneManager *mSceneMgr; + MWWorld::Environment& mEnvironment; + // Path grid stuff + bool mPathgridEnabled; - public: - Debugging(OEngine::Physic::PhysicEngine* engine); - bool toggleRenderMode (int mode); - }; + void togglePathgrid(); + + typedef std::vector CellList; + CellList mActiveCells; + + Ogre::SceneNode *mMwRoot; + + Ogre::SceneNode *mPathGridRoot; + + typedef std::map, Ogre::SceneNode *> ExteriorPathgridNodes; + ExteriorPathgridNodes mExteriorPathgridNodes; + Ogre::SceneNode *mInteriorPathgridNode; + + void enableCellPathgrid(MWWorld::Ptr::CellStore *store); + void disableCellPathgrid(MWWorld::Ptr::CellStore *store); + + // utility + void destroyCellPathgridNode(Ogre::SceneNode *node); + void destroyAttachedObjects(Ogre::SceneNode *node); + + // materials + bool mGridMatsCreated; + void createGridMaterials(); + void destroyGridMaterials(); + + // path grid meshes + Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid); + Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid); + public: + Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine); + ~Debugging(); + bool toggleRenderMode (int mode); + + void cellAdded(MWWorld::Ptr::CellStore* store); + void cellRemoved(MWWorld::Ptr::CellStore* store); + }; } diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index ed218dc97d..cb3c0a204b 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -2,7 +2,9 @@ #include "renderingmanager.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" #include "../mwgui/window_manager.hpp" +#include "renderconst.hpp" #include #include @@ -10,16 +12,24 @@ using namespace MWRender; using namespace Ogre; -LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env) +LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering, MWWorld::Environment* env) : + mInterior(false), mCellX(0), mCellY(0) { mRendering = rend; + mRenderingManager = rendering; mEnvironment = env; - + + mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); + mCameraRotNode = mCameraPosNode->createChildSceneNode(); + mCameraNode = mCameraRotNode->createChildSceneNode(); + mCellCamera = mRendering->getScene()->createCamera("CellCamera"); mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); // look down -y const float sqrt0pt5 = 0.707106781; mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); + + mCameraNode->attachObject(mCellCamera); } LocalMap::~LocalMap() @@ -27,6 +37,12 @@ LocalMap::~LocalMap() deleteBuffers(); } +const Ogre::Vector2 LocalMap::rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle) +{ + return Vector2( Math::Cos(angle) * (p.x - c.x) - Math::Sin(angle) * (p.y - c.y) + c.x, + Math::Sin(angle) * (p.x - c.x) + Math::Cos(angle) * (p.y - c.y) + c.y); +} + void LocalMap::deleteBuffers() { mBuffers.clear(); @@ -65,9 +81,6 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell) { Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); - /// \todo why is this workaround needed? - min *= 1.3; - max *= 1.3; Vector2 length = max-min; // divide into segments @@ -90,11 +103,15 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) { mInterior = false; + mCameraRotNode->setOrientation(Quaternion::IDENTITY); + std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY); int x = cell->cell->data.gridX; int y = cell->cell->data.gridY; + mCameraPosNode->setPosition(Vector3(0,0,0)); + render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name); } @@ -103,17 +120,41 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, { mInterior = true; mBounds = bounds; - - Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y); - Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z); - Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z); - /// \todo why is this workaround needed? - min *= 1.3; - max *= 1.3; + Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y); + + const Vector2& north = mEnvironment->mWorld->getNorthVector(cell); + Radian angle(std::atan2(-north.x, -north.y)); + mAngle = angle.valueRadians(); + mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0)); + + // rotate the cell and merge the rotated corners to the bounding box + Vector2 _center(bounds.getCenter().x, bounds.getCenter().z); + Vector3 _c1 = bounds.getCorner(AxisAlignedBox::NEAR_LEFT_BOTTOM); + Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM); + Vector3 _c3 = bounds.getCorner(AxisAlignedBox::NEAR_RIGHT_BOTTOM); + Vector3 _c4 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM); + Vector2 c1(_c1.x, _c1.z); + Vector2 c2(_c2.x, _c2.z); + Vector2 c3(_c3.x, _c3.z); + Vector2 c4(_c4.x, _c4.z); + c1 = rotatePoint(c1, _center, mAngle); + c2 = rotatePoint(c2, _center, mAngle); + c3 = rotatePoint(c3, _center, mAngle); + c4 = rotatePoint(c4, _center, mAngle); + mBounds.merge(Vector3(c1.x, 0, c1.y)); + mBounds.merge(Vector3(c2.x, 0, c2.y)); + mBounds.merge(Vector3(c3.x, 0, c3.y)); + mBounds.merge(Vector3(c4.x, 0, c4.y)); + + Vector2 center(mBounds.getCenter().x, mBounds.getCenter().z); + + Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); + Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); Vector2 length = max-min; - Vector2 center(bounds.getCenter().x, bounds.getCenter().z); + + mCameraPosNode->setPosition(Vector3(center.x, 0, center.y)); // divide into segments const int segsX = std::ceil( length.x / sSize ); @@ -128,7 +169,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, Vector2 start = min + Vector2(sSize*x,sSize*y); Vector2 newcenter = start + 4096; - render(newcenter.x, newcenter.y, z.y, z.x, sSize, sSize, + render(newcenter.x - center.x, newcenter.y - center.y, z.y, z.x, sSize, sSize, cell->cell->name + "_" + coordStr(x,y)); } } @@ -147,8 +188,9 @@ void LocalMap::render(const float x, const float y, // make everything visible mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); + mRenderingManager->disableLights(); - mCellCamera->setPosition(Vector3(x, zhigh+100000, y)); + mCameraNode->setPosition(Vector3(x, zhigh+100000, y)); //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); mCellCamera->setFarClipDistance(0); // infinite @@ -182,7 +224,8 @@ void LocalMap::render(const float x, const float y, vp->setOverlaysEnabled(false); vp->setShadowsEnabled(false); vp->setBackgroundColour(ColourValue(0, 0, 0)); - //vp->setVisibilityMask( ... ); + vp->setVisibilityMask(RV_Map); + vp->setMaterialScheme("Map"); rtt->update(); @@ -215,13 +258,14 @@ void LocalMap::render(const float x, const float y, //rtt->writeContentsToFile("./" + texture + ".jpg"); } } - + + mRenderingManager->enableLights(); // re-enable fog mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); } -void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction) +void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation) { if (sFogOfWarSkip != 0) { @@ -232,7 +276,19 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& // retrieve the x,y grid coordinates the player is in int x,y; - Vector2 pos(position.x, position.z); + Vector3 _pos(position.x, 0, position.z); + Vector2 pos(_pos.x, _pos.z); + + if (mInterior) + { + pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle); + } + + + Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis(); + + Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); + if (!mInterior) { x = std::ceil(pos.x / sSize)-1; @@ -242,9 +298,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& } else { - Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); - min *= 1.3; - x = std::ceil((pos.x - min.x)/sSize)-1; y = std::ceil((pos.y - min.y)/sSize)-1; @@ -259,20 +312,17 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& u = std::abs((pos.x - (sSize*x))/sSize); v = 1-std::abs((pos.y + (sSize*y))/sSize); texName = "Cell_"+coordStr(x,y); - } else { - Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); - min *= 1.3; - u = (pos.x - min.x - sSize*x)/sSize; v = (pos.y - min.y - sSize*y)/sSize; texName = mInteriorName + "_" + coordStr(x,y); } + mEnvironment->mWindowManager->setPlayerPos(u, v); - mEnvironment->mWindowManager->setPlayerDir(direction.x, -direction.z); + mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z); // explore radius (squared) const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index efbccf8848..95685167c3 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -12,13 +12,15 @@ namespace MWWorld namespace MWRender { + class RenderingManager; + /// /// \brief Local map rendering /// class LocalMap { public: - LocalMap(OEngine::Render::OgreRenderer*, MWWorld::Environment* env); + LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering, MWWorld::Environment* env); ~LocalMap(); /** @@ -44,9 +46,9 @@ namespace MWRender * @remarks This is used to draw a "fog of war" effect * to hide areas on the map the player has not discovered yet. * @param position (OGRE coordinates) - * @param view direction (OGRE coordinates) + * @param camera orientation (OGRE coordinates) */ - void updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction); + void updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation); /** * Save the fog of war for the current cell to disk. @@ -58,6 +60,7 @@ namespace MWRender private: OEngine::Render::OgreRenderer* mRendering; + MWRender::RenderingManager* mRenderingManager; MWWorld::Environment* mEnvironment; // 1024*1024 pixels for a cell @@ -73,6 +76,12 @@ namespace MWRender static const int sSize = 8192; Ogre::Camera* mCellCamera; + Ogre::SceneNode* mCameraNode; + Ogre::SceneNode* mCameraPosNode; + Ogre::SceneNode* mCameraRotNode; + + float mAngle; + const Ogre::Vector2 rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle); void render(const float x, const float y, const float zlow, const float zhigh, diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index ea00919c69..f7877d2ad0 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -1,5 +1,6 @@ #include "npcanimation.hpp" #include "../mwworld/world.hpp" +#include "renderconst.hpp" @@ -11,7 +12,7 @@ NpcAnimation::~NpcAnimation(){ } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)){ +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv){ ESMS::LiveCellRef *ref = ptr.get(); Ogre::Entity* blank = 0; @@ -75,6 +76,28 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O base = mRend.getScene()->createEntity(smodel); + base->setVisibilityFlags(RV_Actors); + bool transparent = false; + for (unsigned int i=0; igetNumSubEntities(); ++i) + { + Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial(); + Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); + while (techIt.hasMoreElements()) + { + Ogre::Technique* tech = techIt.getNext(); + Ogre::Technique::PassIterator passIt = tech->getPassIterator(); + while (passIt.hasMoreElements()) + { + Ogre::Pass* pass = passIt.getNext(); + + if (pass->getDepthWriteEnabled() == false) + transparent = true; + } + } + } + base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); + + base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones //stay in the same place when we skipanim, or open a gui window @@ -111,11 +134,9 @@ void NpcAnimation::updateParts(){ //inv.getSlot(MWWorld::InventoryStore::Slot_Robe); - robe = inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass); - if(robe == inv.end()) - std::cout << "No part\n"; - else - std::cout << "yes part\n"; + //MWWorld::ContainerStoreIterator robe = inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass); + //if(robe == inv.end()) + // ; const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); @@ -271,11 +292,13 @@ std::pair*> NpcAnimation::insert void NpcAnimation::runAnimation(float timepassed){ + if(mStateID != inv.getStateId()){ - mStateID = inv.getStateId(); - updateParts(); + std::cout << "StateID" < #include +#include +#include "renderconst.hpp" using namespace MWRender; @@ -88,18 +90,16 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) NifOgre::NIFLoader::load(mesh); Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh); -/* + Ogre::Vector3 extents = ent->getBoundingBox().getSize(); extents *= insert->getScale(); -// float size = std::max(std::max(extents.x, extents.y), extents.z); + float size = std::max(std::max(extents.x, extents.y), extents.z); - bool small = (size < 250); /// \todo config value + bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Objects"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; -*/ - const bool small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; @@ -113,17 +113,49 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) bounds.scale(insert->getScale()); mBounds[ptr.getCell()].merge(bounds); - if(!mIsStatic) + bool transparent = false; + for (unsigned int i=0; igetNumSubEntities(); ++i) + { + Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); + Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); + while (techIt.hasMoreElements()) + { + Ogre::Technique* tech = techIt.getNext(); + Ogre::Technique::PassIterator passIt = tech->getPassIterator(); + while (passIt.hasMoreElements()) + { + Ogre::Pass* pass = passIt.getNext(); + + if (pass->getDepthWriteEnabled() == false) + transparent = true; + } + } + } + + if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects")) { insert->attachObject(ent); - ent->setRenderingDistance(small ? 2500 : 0); /// \todo config value + ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); + ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); + ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); } else { Ogre::StaticGeometry* sg = 0; - if (small) +/* if (transparent) + { + if( mStaticGeometryAlpha.find(ptr.getCell()) == mStaticGeometryAlpha.end()) + { + uniqueID = uniqueID +1; + sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); + mStaticGeometryAlpha[ptr.getCell()] = sg; + } + else + sg = mStaticGeometryAlpha[ptr.getCell()]; + } + else*/ if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { @@ -131,7 +163,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; - sg->setRenderingDistance(2500); /// \todo config value + sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; @@ -159,6 +191,10 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); + sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); + + sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); + mRenderer.getScene()->destroyEntity(ent); } } @@ -169,6 +205,7 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f assert(insert); Ogre::Light *light = mRenderer.getScene()->createLight(); light->setDiffuseColour (r, g, b); + mLights.push_back(light->getName()); float cval=0.0f, lval=0.0f, qval=0.0f; @@ -251,6 +288,13 @@ void Objects::removeCell(MWWorld::Ptr::CellStore* store) mRenderer.getScene()->destroyStaticGeometry (sg); sg = 0; } + /*if(mStaticGeometryAlpha.find(store) != mStaticGeometryAlpha.end()) + { + Ogre::StaticGeometry* sg = mStaticGeometryAlpha[store]; + mStaticGeometryAlpha.erase(store); + mRenderer.getScene()->destroyStaticGeometry (sg); + sg = 0; + }*/ if(mBounds.find(store) != mBounds.end()) mBounds.erase(store); @@ -268,9 +312,45 @@ void Objects::buildStaticGeometry(ESMS::CellStore& cell) Ogre::StaticGeometry* sg = mStaticGeometrySmall[&cell]; sg->build(); } + /*if(mStaticGeometryAlpha.find(&cell) != mStaticGeometryAlpha.end()) + { + Ogre::StaticGeometry* sg = mStaticGeometryAlpha[&cell]; + sg->build(); + }*/ } Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell) { return mBounds[cell]; } + +void Objects::enableLights() +{ + std::vector::iterator it = mLights.begin(); + while (it != mLights.end()) + { + if (mMwRoot->getCreator()->hasLight(*it)) + { + mMwRoot->getCreator()->getLight(*it)->setVisible(true); + ++it; + } + else + it = mLights.erase(it); + } +} + +void Objects::disableLights() +{ + std::vector::iterator it = mLights.begin(); + while (it != mLights.end()) + { + if (mMwRoot->getCreator()->hasLight(*it)) + { + mMwRoot->getCreator()->getLight(*it)->setVisible(false); + ++it; + } + else + it = mLights.erase(it); + } +} + diff --git a/apps/openmw/mwrender/objects.hpp b/apps/openmw/mwrender/objects.hpp index 265de875be..0c19f9f33f 100644 --- a/apps/openmw/mwrender/objects.hpp +++ b/apps/openmw/mwrender/objects.hpp @@ -15,7 +15,9 @@ class Objects{ std::map mCellSceneNodes; std::map mStaticGeometry; std::map mStaticGeometrySmall; + //std::map mStaticGeometryAlpha; std::map mBounds; + std::vector mLights; Ogre::SceneNode* mMwRoot; bool mIsStatic; static int uniqueID; @@ -44,6 +46,9 @@ public: void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius); + void enableLights(); + void disableLights(); + Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*); ///< get a bounding box that encloses all objects in the specified cell diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 781b522b63..d789b8c4e9 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -1,4 +1,5 @@ #include "occlusionquery.hpp" +#include "renderconst.hpp" #include #include @@ -6,6 +7,7 @@ #include #include #include +#include using namespace MWRender; using namespace Ogre; @@ -39,9 +41,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod return; } - // This means that everything up to RENDER_QUEUE_MAIN can occlude the objects that are tested - const int queue = RENDER_QUEUE_MAIN+1; - MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting"); MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels"); matQueryArea->setDepthWriteEnabled(false); @@ -64,14 +63,14 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBQueryTotal->setDefaultDimensions(150, 150); mBBQueryTotal->createBillboard(Vector3::ZERO); mBBQueryTotal->setMaterialName("QueryTotalPixels"); - mBBQueryTotal->setRenderQueueGroup(queue+1); + mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBNodeReal->attachObject(mBBQueryTotal); mBBQueryVisible = mRendering->getScene()->createBillboardSet(1); mBBQueryVisible->setDefaultDimensions(150, 150); mBBQueryVisible->createBillboard(Vector3::ZERO); mBBQueryVisible->setMaterialName("QueryVisiblePixels"); - mBBQueryVisible->setRenderQueueGroup(queue+1); + mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBNodeReal->attachObject(mBBQueryVisible); mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1); @@ -79,7 +78,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003); mBBQuerySingleObject->createBillboard(Vector3::ZERO); mBBQuerySingleObject->setMaterialName("QueryVisiblePixels"); - mBBQuerySingleObject->setRenderQueueGroup(queue); + mBBQuerySingleObject->setRenderQueueGroup(RQG_OcclusionQuery); mObjectNode->attachObject(mBBQuerySingleObject); mRendering->getScene()->addRenderObjectListener(this); @@ -152,7 +151,7 @@ void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocati * this can happen for example if the object that is tested is outside of the view frustum * to prevent this, check if the queries have been performed after everything has been rendered and if not, start them manually */ - if (queueGroupId == RENDER_QUEUE_SKIES_LATE) + if (queueGroupId == RQG_SkiesLate) { if (mWasVisible == false && mDoQuery) { diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp new file mode 100644 index 0000000000..2c7f9e9acb --- /dev/null +++ b/apps/openmw/mwrender/renderconst.hpp @@ -0,0 +1,62 @@ +#ifndef GAME_RENDER_CONST_H +#define GAME_RENDER_CONST_H + +#include + +namespace MWRender +{ + +// Render queue groups +enum RenderQueueGroups +{ + // Sky early (atmosphere, clouds, moons) + RQG_SkiesEarly = Ogre::RENDER_QUEUE_SKIES_EARLY, + + RQG_Main = Ogre::RENDER_QUEUE_MAIN, + + RQG_Water = Ogre::RENDER_QUEUE_7+1, + + RQG_Alpha = Ogre::RENDER_QUEUE_MAIN, + + RQG_UnderWater = Ogre::RENDER_QUEUE_7+1, + + RQG_OcclusionQuery = Ogre::RENDER_QUEUE_8, + + // Sky late (sun & sun flare) + RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE +}; + +// Visibility flags +enum VisibilityFlags +{ + // Terrain + RV_Terrain = 1, + + // Statics (e.g. trees, houses) + RV_Statics = 2, + + // Small statics + RV_StaticsSmall = 4, + + // Water + RV_Water = 8, + + // Actors (player, npcs, creatures) + RV_Actors = 16, + + // Misc objects (containers, dynamic objects) + RV_Misc = 32, + + RV_Sky = 64, + + // Sun glare (not visible in reflection) + RV_Glare = 128, + + RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water, + + /// \todo markers (normally hidden) +}; + +} + +#endif diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index bbddd325a1..8d84af98f4 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -12,6 +12,7 @@ #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwworld/ptr.hpp" #include +#include using namespace MWRender; @@ -20,22 +21,53 @@ using namespace Ogre; namespace MWRender { RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment) -:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mDebugging(engine) + :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0) { - mRendering.createScene("PlayerCam", 55, 5); + mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); mTerrainManager = new TerrainManager(mRendering.getScene(), environment); + mWater = 0; + //The fog type must be set before any terrain objects are created as if the //fog type is set to FOG_NONE then the initially created terrain won't have any fog configureFog(1, ColourValue(1,1,1)); // Set default mipmap level (NB some APIs ignore this) - TextureManager::getSingleton().setDefaultNumMipmaps(5); + TextureManager::getSingleton().setDefaultNumMipmaps(Settings::Manager::getInt("num mipmaps", "General")); + + // Set default texture filtering options + TextureFilterOptions tfo; + std::string filter = Settings::Manager::getString("texture filtering", "General"); + if (filter == "anisotropic") tfo = TFO_ANISOTROPIC; + else if (filter == "trilinear") tfo = TFO_TRILINEAR; + else /* if (filter == "bilinear") */ tfo = TFO_BILINEAR; + + MaterialManager::getSingleton().setDefaultTextureFiltering(tfo); + MaterialManager::getSingleton().setDefaultAnisotropy(Settings::Manager::getInt("anisotropy", "General")); // Load resources ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + // disable unsupported effects + const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); + if (caps->getNumMultiRenderTargets() < 2) + Settings::Manager::setBool("shader", "Water", false); + + // note that the order is important here + if (useMRT()) + { + CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbuffer"); + CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true); + CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "Underwater"); + CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbufferFinalizer"); + CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true); + } + else + { + CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "UnderwaterNoMRT"); + } + // Turn the entire scene (represented by the 'root' node) -90 // degrees around the x axis. This makes Z go upwards, and Y go into // the screen (when x is to the right.) This is the orientation that @@ -52,18 +84,17 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const Ogre::SceneNode *cameraYawNode = playerNode->createChildSceneNode(); Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode(); cameraPitchNode->attachObject(mRendering.getCamera()); - + //mSkyManager = 0; mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera(), &environment); mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); - mWater = 0; - mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mSun = 0; - mLocalMap = new MWRender::LocalMap(&mRendering, &environment); + mDebugging = new Debugging(mMwRoot, environment, engine); + mLocalMap = new MWRender::LocalMap(&mRendering, this, &environment); } RenderingManager::~RenderingManager () @@ -71,6 +102,7 @@ RenderingManager::~RenderingManager () //TODO: destroy mSun? delete mPlayer; delete mSkyManager; + delete mDebugging; delete mTerrainManager; delete mLocalMap; delete mOcclusionQuery; @@ -101,6 +133,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store) { mObjects.removeCell(store); mActors.removeCell(store); + mDebugging->cellRemoved(store); if (store->cell->isExterior()) mTerrainManager->cellRemoved(store); } @@ -108,8 +141,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store) void RenderingManager::removeWater () { if(mWater){ - delete mWater; - mWater = 0; + mWater->setActive(false); } } @@ -122,8 +154,10 @@ void RenderingManager::toggleWater() void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store) { mObjects.buildStaticGeometry (*store); + mDebugging->cellAdded(store); if (store->cell->isExterior()) mTerrainManager->cellAdded(store); + waterAdded(store); } void RenderingManager::addObject (const MWWorld::Ptr& ptr){ @@ -173,22 +207,21 @@ void RenderingManager::update (float duration){ mRendering.update(duration); - mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealDirection() ); + mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); checkUnderwater(); } void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ if(store->cell->data.flags & store->cell->HasWater){ if(mWater == 0) - mWater = new MWRender::Water(mRendering.getCamera(), store->cell); + mWater = new MWRender::Water(mRendering.getCamera(), mSkyManager, store->cell); else mWater->changeCell(store->cell); - //else - + mWater->setActive(true); } else removeWater(); - + } void RenderingManager::setWaterHeight(const float height) @@ -226,7 +259,7 @@ void RenderingManager::skySetDate (int day, int month) int RenderingManager::skyGetMasserPhase() const { - + return mSkyManager->getMasserPhase(); } @@ -242,17 +275,31 @@ void RenderingManager::skySetMoonColour (bool red){ bool RenderingManager::toggleRenderMode(int mode) { - if (mode == MWWorld::World::Render_CollisionDebug) - return mDebugging.toggleRenderMode(mode); + if (mode != MWWorld::World::Render_Wireframe) + return mDebugging->toggleRenderMode(mode); else // if (mode == MWWorld::World::Render_Wireframe) { if (mRendering.getCamera()->getPolygonMode() == PM_SOLID) { + // disable compositors + if (useMRT()) + { + CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", false); + CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", false); + } + mRendering.getCamera()->setPolygonMode(PM_WIREFRAME); return true; } else { + // re-enable compositors + if (useMRT()) + { + CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true); + CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true); + } + mRendering.getCamera()->setPolygonMode(PM_SOLID); return false; } @@ -261,27 +308,29 @@ bool RenderingManager::toggleRenderMode(int mode) void RenderingManager::configureFog(ESMS::CellStore &mCell) { - Ogre::ColourValue color; - color.setAsABGR (mCell.cell->ambi.fog); + Ogre::ColourValue color; + color.setAsABGR (mCell.cell->ambi.fog); - configureFog(mCell.cell->ambi.fogDensity, color); + configureFog(mCell.cell->ambi.fogDensity, color); } void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) -{ - /// \todo make the viewing distance and fog start/end configurable +{ + float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance"); - // right now we load 3x3 cells, so the maximum viewing distance we - // can allow (to prevent objects suddenly popping up) equals: - // 8192 * 0.69 - // ^ cell size ^ minimum density value used (clear weather) - float low = 5652.48 / density / 2.f; - float high = 5652.48 / density; + float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance"); + float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance"); - mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high); - - mRendering.getCamera()->setFarClipDistance ( high ); - mRendering.getViewport()->setBackgroundColour (colour); + mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high); + + mRendering.getCamera()->setFarClipDistance ( max / density ); + mRendering.getViewport()->setBackgroundColour (colour); + + CompositorInstance* inst = CompositorManager::getSingleton().getCompositorChain(mRendering.getViewport())->getCompositor("gbuffer"); + if (inst != 0) + inst->getCompositor()->getTechnique(0)->getTargetPass(0)->getPass(0)->setClearColour(colour); + if (mWater) + mWater->setViewportBackground(colour); } @@ -308,41 +357,43 @@ void RenderingManager::setAmbientMode() void RenderingManager::configureAmbient(ESMS::CellStore &mCell) { - mAmbientColor.setAsABGR (mCell.cell->ambi.ambient); - setAmbientMode(); + mAmbientColor.setAsABGR (mCell.cell->ambi.ambient); + setAmbientMode(); - // Create a "sun" that shines light downwards. It doesn't look - // completely right, but leave it for now. - if(!mSun) - { - mSun = mRendering.getScene()->createLight(); - } - Ogre::ColourValue colour; - colour.setAsABGR (mCell.cell->ambi.sunlight); - mSun->setDiffuseColour (colour); - mSun->setType(Ogre::Light::LT_DIRECTIONAL); - mSun->setDirection(0,-1,0); + // Create a "sun" that shines light downwards. It doesn't look + // completely right, but leave it for now. + if(!mSun) + { + mSun = mRendering.getScene()->createLight(); + } + Ogre::ColourValue colour; + colour.setAsABGR (mCell.cell->ambi.sunlight); + mSun->setDiffuseColour (colour); + mSun->setType(Ogre::Light::LT_DIRECTIONAL); + mSun->setDirection(0,-1,0); } // Switch through lighting modes. void RenderingManager::toggleLight() { - if (mAmbientMode==2) - mAmbientMode = 0; - else - ++mAmbientMode; + if (mAmbientMode==2) + mAmbientMode = 0; + else + ++mAmbientMode; - switch (mAmbientMode) - { - case 0: std::cout << "Setting lights to normal\n"; break; - case 1: std::cout << "Turning the lights up\n"; break; - case 2: std::cout << "Turning the lights to full\n"; break; - } + switch (mAmbientMode) + { + case 0: std::cout << "Setting lights to normal\n"; break; + case 1: std::cout << "Turning the lights up\n"; break; + case 2: std::cout << "Turning the lights to full\n"; break; + } - setAmbientMode(); + setAmbientMode(); } -void RenderingManager::checkUnderwater(){ - if(mWater){ +void RenderingManager::checkUnderwater() +{ + if(mWater) + { mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y ); } } @@ -361,6 +412,7 @@ void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr) void RenderingManager::setSunColour(const Ogre::ColourValue& colour) { mSun->setDiffuseColour(colour); + mSun->setSpecularColour(colour); mTerrainManager->setDiffuse(colour); } @@ -382,10 +434,10 @@ void RenderingManager::sunDisable() void RenderingManager::setSunDirection(const Ogre::Vector3& direction) { - // direction * -1 (because 'direction' is camera to sun vector and not sun to camera), + // direction * -1 (because 'direction' is camera to sun vector and not sun to camera), // then convert from MW to ogre coordinates (swap y,z and make y negative) if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.z, direction.y)); - + mSkyManager->setSunDirection(direction); } @@ -407,4 +459,19 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell) mLocalMap->saveFogOfWar(cell); } +void RenderingManager::disableLights() +{ + mObjects.disableLights(); +} + +void RenderingManager::enableLights() +{ + mObjects.enableLights(); +} + +const bool RenderingManager::useMRT() +{ + return Settings::Manager::getBool("shader", "Water"); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 01decf57ca..da9c55cb5a 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -31,11 +31,8 @@ namespace Ogre { - class Camera; - class Viewport; class SceneManager; class SceneNode; - class RaySceneQuery; class Quaternion; class Vector3; } @@ -84,6 +81,8 @@ class RenderingManager: private RenderingInterface { void removeWater(); + static const bool useMRT(); + void preCellChange (MWWorld::Ptr::CellStore* store); ///< this event is fired immediately before changing cell @@ -109,6 +108,9 @@ class RenderingManager: private RenderingInterface { void sunEnable(); void sunDisable(); + void disableLights(); + void enableLights(); + bool occlusionQuerySupported() { return mOcclusionQuery->supported(); }; OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; }; @@ -174,7 +176,8 @@ class RenderingManager: private RenderingInterface { OEngine::Physic::PhysicEngine* mPhysicsEngine; MWRender::Player *mPlayer; - MWRender::Debugging mDebugging; + + MWRender::Debugging *mDebugging; MWRender::LocalMap* mLocalMap; }; diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 2fdf9b2cd6..188ec3b831 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -12,7 +12,8 @@ #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" -#include "occlusionquery.hpp" +#include "renderconst.hpp" +#include "renderingmanager.hpp" using namespace MWRender; using namespace Ogre; @@ -60,6 +61,11 @@ Vector3 BillboardObject::getPosition() const return Vector3(p.x, -p.z, p.y); } +void BillboardObject::setVisibilityFlags(int flags) +{ + mBBSet->setVisibilityFlags(flags); +} + void BillboardObject::setColour(const ColourValue& pColour) { mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour); @@ -89,9 +95,9 @@ void BillboardObject::init(const String& textureName, /// \todo These billboards are not 100% correct, might want to revisit them later mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1); mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize); - mBBSet->setRenderQueueGroup(RENDER_QUEUE_MAIN+2); mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON); mBBSet->setCommonDirection( -position.normalisedCopy() ); + mBBSet->setVisibilityFlags(RV_Sky); mNode = rootNode->createChildSceneNode(); mNode->setPosition(finalPosition); mNode->attachObject(mBBSet); @@ -109,6 +115,65 @@ void BillboardObject::init(const String& textureName, p->createTextureUnitState(textureName); mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount)); + HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); + HighLevelGpuProgramPtr vshader; + if (mgr.resourceExists("BBO_VP")) + vshader = mgr.getByName("BBO_VP"); + else + vshader = mgr.createProgram("BBO_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM); + vshader->setParameter("profiles", "vs_2_x arbvp1"); + vshader->setParameter("entry_point", "main_vp"); + StringUtil::StrStreamType outStream; + outStream << + "void main_vp( \n" + " float4 position : POSITION, \n" + " in float2 uv : TEXCOORD0, \n" + " out float2 oUV : TEXCOORD0, \n" + " out float4 oPosition : POSITION, \n" + " uniform float4x4 worldViewProj \n" + ") \n" + "{ \n" + " oUV = uv; \n" + " oPosition = mul( worldViewProj, position ); \n" + "}"; + vshader->setSource(outStream.str()); + vshader->load(); + vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); + mMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName()); + + HighLevelGpuProgramPtr fshader; + if (mgr.resourceExists("BBO_FP")) + fshader = mgr.getByName("BBO_FP"); + else + fshader = mgr.createProgram("BBO_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_FRAGMENT_PROGRAM); + + fshader->setParameter("profiles", "ps_2_x arbfp1"); + fshader->setParameter("entry_point", "main_fp"); + StringUtil::StrStreamType outStream2; + outStream2 << + "void main_fp( \n" + " in float2 uv : TEXCOORD0, \n" + " out float4 oColor : COLOR, \n"; + if (RenderingManager::useMRT()) outStream2 << + " out float4 oColor1 : COLOR1, \n"; + outStream2 << + " uniform sampler2D texture : TEXUNIT0, \n" + " uniform float4 diffuse, \n" + " uniform float4 emissive \n" + ") \n" + "{ \n" + " float4 tex = tex2D(texture, uv); \n" + " oColor = float4(emissive.xyz,1) * tex * float4(1,1,1,diffuse.a); \n"; + if (RenderingManager::useMRT()) outStream2 << + " oColor1 = float4(1, 0, 0, 1); \n"; + outStream2 << + "}"; + fshader->setSource(outStream2.str()); + fshader->load(); + fshader->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR); + fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); + mMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName()); + bodyCount++; } @@ -157,7 +222,10 @@ Moon::Moon( const String& textureName, outStream2 << "void main_fp( \n" " in float2 uv : TEXCOORD0, \n" - " out float4 oColor : COLOR, \n" + " out float4 oColor : COLOR, \n"; + if (RenderingManager::useMRT()) outStream2 << + " out float4 oColor1 : COLOR1, \n"; + outStream2 << " uniform sampler2D texture : TEXUNIT0, \n" " uniform float4 skyColour, \n" " uniform float4 diffuse, \n" @@ -165,7 +233,10 @@ Moon::Moon( const String& textureName, ") \n" "{ \n" " float4 tex = tex2D(texture, uv); \n" - " oColor = float4(emissive.xyz,1) * tex; \n" + " oColor = float4(emissive.xyz,1) * tex; \n"; + if (RenderingManager::useMRT()) outStream2 << + " oColor1 = float4(1, 0, 0, 1); \n"; + outStream2 << // use a circle for the alpha (compute UV distance to center) // looks a bit bad because its not filtered on the edges, // but it's cheaper than a seperate alpha texture. @@ -358,15 +429,17 @@ void SkyManager::create() mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode); mSecunda->setType(Moon::Type_Secunda); - mSecunda->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+4); + mSecunda->setRenderQueue(RQG_SkiesEarly+4); mMasser = new Moon("textures\\tx_masser_full.dds", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode); - mMasser->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+3); + mMasser->setRenderQueue(RQG_SkiesEarly+3); mMasser->setType(Moon::Type_Masser); mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode); + mSun->setRenderQueue(RQG_SkiesEarly+4); mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode); - mSunGlare->setRenderQueue(RENDER_QUEUE_SKIES_LATE); + mSunGlare->setRenderQueue(RQG_SkiesLate); + mSunGlare->setVisibilityFlags(RV_Glare); HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); @@ -375,7 +448,8 @@ void SkyManager::create() /// \todo sky_night_02.nif (available in Bloodmoon) MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif"); Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif"); - night1_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+1); + night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1); + night1_ent->setVisibilityFlags(RV_Sky); mAtmosphereNight = mRootNode->createChildSceneNode(); mAtmosphereNight->attachObject(night1_ent); @@ -413,7 +487,10 @@ void SkyManager::create() outStream5 << "void main_fp( \n" " in float2 uv : TEXCOORD0, \n" - " out float4 oColor : COLOR, \n" + " out float4 oColor : COLOR, \n"; + if (RenderingManager::useMRT()) outStream5 << + " out float4 oColor1 : COLOR1, \n"; + outStream5 << " in float fade : TEXCOORD1, \n" " uniform sampler2D texture : TEXUNIT0, \n" " uniform float opacity, \n" @@ -421,7 +498,10 @@ void SkyManager::create() " uniform float4 emissive \n" ") \n" "{ \n" - " oColor = tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n" + " oColor = tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n"; + if (RenderingManager::useMRT()) outStream5 << + " oColor1 = float4(1, 0, 0, 1); \n"; + outStream5 << "}"; stars_fp->setSource(outStream5.str()); stars_fp->load(); @@ -448,7 +528,8 @@ void SkyManager::create() ModVertexAlpha(atmosphere_ent, 0); - atmosphere_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY); + atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly); + atmosphere_ent->setVisibilityFlags(RV_Sky); mAtmosphereDay = mRootNode->createChildSceneNode(); mAtmosphereDay->attachObject(atmosphere_ent); mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial(); @@ -466,26 +547,52 @@ void SkyManager::create() " float4 position : POSITION, \n" " in float4 color : COLOR, \n" " out float4 oPosition : POSITION, \n" - " out float4 oColor : COLOR, \n" - " uniform float4 emissive, \n" + " out float4 oVertexColor : TEXCOORD0, \n" " uniform float4x4 worldViewProj \n" ") \n" "{ \n" " oPosition = mul( worldViewProj, position ); \n" - " oColor = color * emissive; \n" + " oVertexColor = color; \n" "}"; vshader->setSource(outStream.str()); vshader->load(); vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); - vshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName()); - mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(""); + + HighLevelGpuProgramPtr fshader = mgr.createProgram("Atmosphere_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "cg", GPT_FRAGMENT_PROGRAM); + + fshader->setParameter("profiles", "ps_2_x arbfp1"); + fshader->setParameter("entry_point", "main_fp"); + + StringUtil::StrStreamType _outStream; + _outStream << + "void main_fp( \n" + " in float4 iVertexColor : TEXCOORD0, \n" + " out float4 oColor : COLOR, \n"; + if (RenderingManager::useMRT()) _outStream << + " out float4 oColor1 : COLOR1, \n"; + _outStream << + " uniform float4 emissive \n" + ") \n" + "{ \n" + " oColor = iVertexColor * emissive; \n"; + if (RenderingManager::useMRT()) _outStream << + " oColor1 = float4(1, 0, 0, 1); \n"; + _outStream << + "}"; + fshader->setSource(_outStream.str()); + fshader->load(); + + fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); + mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName()); // Clouds NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif"); Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif"); - clouds_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+5); + clouds_ent->setVisibilityFlags(RV_Sky); + clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5); SceneNode* clouds_node = mRootNode->createChildSceneNode(); clouds_node->attachObject(clouds_ent); mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial(); @@ -525,8 +632,11 @@ void SkyManager::create() outStream2 << "void main_fp( \n" " in float2 uv : TEXCOORD0, \n" - " out float4 oColor : COLOR, \n" " in float4 color : TEXCOORD1, \n" + " out float4 oColor : COLOR, \n"; + if (RenderingManager::useMRT()) outStream2 << + " out float4 oColor1 : COLOR1, \n"; + outStream2 << " uniform sampler2D texture : TEXUNIT0, \n" " uniform sampler2D secondTexture : TEXUNIT1, \n" " uniform float transitionFactor, \n" @@ -538,7 +648,10 @@ void SkyManager::create() "{ \n" " uv += float2(0,1) * time * speed * 0.003; \n" // Scroll in y direction " float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n" - " oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n" + " oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n"; + if (RenderingManager::useMRT()) outStream2 << + " oColor1 = float4(1, 0, 0, 1); \n"; + outStream2 << "}"; mCloudFragmentShader->setSource(outStream2.str()); mCloudFragmentShader->load(); @@ -734,7 +847,8 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather) strength = 1.f; mSunGlare->setVisibility(weather.mGlareView * mGlareFade * strength); - mSun->setVisibility(mGlareFade >= 0.5 ? weather.mGlareView * mGlareFade * strength : 0); + + mSun->setVisibility(weather.mGlareView * strength); mAtmosphereNight->setVisible(weather.mNight && mEnabled); } @@ -746,6 +860,7 @@ void SkyManager::setGlare(const float glare) Vector3 SkyManager::getRealSunPos() { + if (!mCreated) return Vector3(0,0,0); return mSun->getNode()->_getDerivedPosition(); } @@ -836,3 +951,18 @@ Ogre::SceneNode* SkyManager::getSunNode() if (!mCreated) return 0; return mSun->getNode(); } + +void SkyManager::setSkyPosition(const Ogre::Vector3& position) +{ + mRootNode->_setDerivedPosition(position); +} + +void SkyManager::resetSkyPosition() +{ + mRootNode->setPosition(0,0,0); +} + +void SkyManager::scaleSky(float scale) +{ + mRootNode->setScale(scale, scale, scale); +} diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index baf5933cbc..64d5c16a03 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -36,24 +36,25 @@ namespace MWRender BillboardObject(); virtual ~BillboardObject() {} - + void setColour(const Ogre::ColourValue& pColour); void setPosition(const Ogre::Vector3& pPosition); void setVisible(const bool visible); void setRenderQueue(unsigned int id); + void setVisibilityFlags(int flags); void setSize(const float size); Ogre::Vector3 getPosition() const; - + void setVisibility(const float visibility); - + Ogre::SceneNode* getNode(); - + protected: virtual void init(const Ogre::String& textureName, const float size, const Ogre::Vector3& position, Ogre::SceneNode* rootNode); - + Ogre::SceneNode* mNode; Ogre::MaterialPtr mMaterial; Ogre::BillboardSet* mBBSet; @@ -71,9 +72,9 @@ namespace MWRender const Ogre::Vector3& position, Ogre::SceneNode* rootNode ); - + virtual ~Moon() {} - + enum Phase { Phase_New = 0, @@ -85,20 +86,20 @@ namespace MWRender Phase_WaningHalf, Phase_WaningCrescent }; - + enum Type { Type_Masser = 0, Type_Secunda }; - + void setPhase(const Phase& phase); void setType(const Type& type); void setSkyColour(const Ogre::ColourValue& colour); - + Phase getPhase() const; unsigned int getPhaseInt() const; - + private: Type mType; Phase mPhase; @@ -168,6 +169,10 @@ namespace MWRender void setGlare(const float glare); Ogre::Vector3 getRealSunPos(); + void setSkyPosition(const Ogre::Vector3& position); + void resetSkyPosition(); + void scaleSky(float scale); + private: bool mCreated; @@ -180,21 +185,21 @@ namespace MWRender BillboardObject* mSunGlare; Moon* mMasser; Moon* mSecunda; - + Ogre::Viewport* mViewport; Ogre::SceneNode* mRootNode; Ogre::SceneManager* mSceneMgr; - + Ogre::SceneNode* mAtmosphereDay; Ogre::SceneNode* mAtmosphereNight; - + Ogre::MaterialPtr mCloudMaterial; Ogre::MaterialPtr mAtmosphereMaterial; - + Ogre::MaterialPtr mStarsMaterials[7]; - + Ogre::HighLevelGpuProgramPtr mCloudFragmentShader; - + // remember some settings so we don't have to apply them again if they didnt change Ogre::String mClouds; Ogre::String mNextClouds; @@ -204,17 +209,17 @@ namespace MWRender float mStarsOpacity; Ogre::ColourValue mCloudColour; Ogre::ColourValue mSkyColour; - + Ogre::Overlay* mThunderOverlay; Ogre::TextureUnitState* mThunderTextureUnit; - + float mRemainingTransitionTime; - + float mGlare; // target float mGlareFade; // actual - + void ModVertexAlpha(Ogre::Entity* ent, unsigned int meshType); - + bool mEnabled; bool mSunEnabled; bool mMasserEnabled; diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 8877215653..67dd4e0b05 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -6,6 +6,7 @@ #include "terrainmaterial.hpp" #include "terrain.hpp" +#include "renderconst.hpp" using namespace Ogre; @@ -98,7 +99,10 @@ namespace MWRender ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY); if ( land != NULL ) { - land->loadData(); + if (!land->dataLoaded) + { + land->loadData(); + } } //split the cell terrain into four segments @@ -159,6 +163,8 @@ namespace MWRender x * numTextures, y * numTextures, numTextures, indexes); + terrain->setVisibilityFlags(RV_Terrain); + terrain->setRenderQueueGroup(RQG_Main); if ( land && land->landData->usingColours ) { @@ -420,7 +426,11 @@ namespace MWRender ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY); if ( land != NULL ) { - land->loadData(); + if (!land->dataLoaded) + { + land->loadData(); + } + return land->landData ->textures[y * ESM::Land::LAND_TEXTURE_SIZE + x]; } diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 67ebf45af6..87798006c3 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -36,7 +36,8 @@ THE SOFTWARE. #include "OgreHardwarePixelBuffer.h" #include "OgreShadowCameraSetupPSSM.h" -#define POINTLIGHTS +#include +#include "renderingmanager.hpp" namespace Ogre { @@ -220,22 +221,10 @@ namespace Ogre } - int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const - { - #ifndef POINTLIGHTS - return 1; - #else - // number of supported lights depends on the number of available constant registers, - // which in turn depends on the shader profile used - if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0") - || GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0") - || GpuProgramManager::getSingleton().isSyntaxSupported("fp40") - ) - return 32; - else - return 8; - #endif - } + int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const + { + return Settings::Manager::getInt("num lights", "Terrain"); + } //--------------------------------------------------------------------- MaterialPtr TerrainMaterialGeneratorB::SM2Profile::generate(const Terrain* terrain) { @@ -565,10 +554,14 @@ namespace Ogre { params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); - params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); + if (prof->getNumberOfLightsSupported() > 1) + params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); //params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i); } - + + if (MWRender::RenderingManager::useMRT()) + params->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE); + params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); @@ -764,12 +757,7 @@ namespace Ogre ret->unload(); } - if(prof->isLayerNormalMappingEnabled() || prof->isLayerParallaxMappingEnabled()) - ret->setParameter("profiles", "ps_3_0 ps_2_x fp40 arbfp1"); - //else - //ret->setParameter("profiles", "ps_3_0 ps_2_0 fp30 arbfp1"); - else // fp30 doesn't work (black terrain) - ret->setParameter("profiles", "ps_3_0 ps_2_x fp40 arbfp1"); + ret->setParameter("profiles", "ps_3_0 ps_2_x fp40 arbfp1"); ret->setParameter("entry_point", "main_fp"); return ret; @@ -928,7 +916,7 @@ namespace Ogre outStream << - "float4 main_fp(\n" + "void main_fp(\n" "float4 position : TEXCOORD0,\n"; uint texCoordSet = 1; @@ -980,10 +968,9 @@ namespace Ogre //"uniform float3 lightSpecularColour"<getNumberOfLightsSupported() > 1) + outStream << + "uniform float4 lightAttenuation"<getNumberOfLightsSupported() > 1) + outStream << "float d; \n" "float attn; \n"; - #endif outStream << " eyeDir = normalize(eyeDir); \n"; @@ -1144,13 +1137,12 @@ namespace Ogre outStream << " float3 halfAngle"<getNumberOfLightsSupported() > 1) outStream << // pre-multiply light color with attenuation factor "d = length( lightDir"<getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; if (fog) { @@ -1351,7 +1347,12 @@ namespace Ogre } // Final return - outStream << " return outputCol;\n" + outStream << " oColor = outputCol;\n"; + + if (MWRender::RenderingManager::useMRT()) outStream << + " oColor1 = float4(uvMisc.z / far, 0, 0, 1); \n"; + + outStream << "}\n"; } @@ -1525,14 +1526,6 @@ namespace Ogre } } - - if (prof->getReceiveDynamicShadowsPSSM()) - { - outStream << - " // pass cam depth\n" - " oUVMisc.z = oPos.z;\n"; - } - } //--------------------------------------------------------------------- void TerrainMaterialGeneratorB::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsParams( diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 9de55e3a59..7981def0b8 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -1,29 +1,43 @@ #include "water.hpp" +#include +#include "sky.hpp" +#include "renderingmanager.hpp" + +using namespace Ogre; namespace MWRender { -Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) : +Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), - mIsUnderwater(false) + mIsUnderwater(false), mVisibilityFlags(0), + mReflectionTarget(0), mActive(1) { + mSky = sky; + try { - Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "Water", -1); - Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false); + CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false); } catch(...) {} mTop = cell->water; mIsUnderwater = false; - mWaterPlane = Ogre::Plane(Ogre::Vector3::UNIT_Y, 0); + mWaterPlane = Plane(Vector3::UNIT_Y, 0); - Ogre::MeshManager::getSingleton().createPlane("water", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,5, Ogre::Vector3::UNIT_Z); + MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Z); mWater = mSceneManager->createEntity("water"); + mWater->setVisibilityFlags(RV_Water); + mWater->setRenderQueueGroup(RQG_Water); - mWater->setMaterialName("Examples/Water0"); + mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") + + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") + + RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water") + + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") + + RV_Misc * Settings::Manager::getBool("reflect misc", "Water") + + RV_Sky; mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); mWaterNode->setPosition(0, mTop, 0); @@ -33,18 +47,51 @@ Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) : mWaterNode->setPosition(getSceneNodeCoordinates(cell->data.gridX, cell->data.gridY)); } mWaterNode->attachObject(mWater); + + // Create rendertarget for reflection + int rttsize = Settings::Manager::getInt("rtt size", "Water"); + + if (Settings::Manager::getBool("shader", "Water")) + { + TexturePtr tex = TextureManager::getSingleton().createManual("WaterReflection", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_R8G8B8, TU_RENDERTARGET); + + RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); + Viewport* vp = rtt->addViewport(mCamera); + vp->setOverlaysEnabled(false); + vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); + vp->setShadowsEnabled(false); + vp->setVisibilityMask( mVisibilityFlags ); + rtt->addListener(this); + rtt->setActive(true); + + mReflectionTarget = rtt; + } + + mCompositorName = RenderingManager::useMRT() ? "Underwater" : "UnderwaterNoMRT"; + + createMaterial(); + mWater->setMaterial(mMaterial); + + mUnderwaterEffect = Settings::Manager::getBool("underwater effect", "Water"); } +void Water::setActive(bool active) +{ + mActive = active; + if (mReflectionTarget) mReflectionTarget->setActive(active && !mIsUnderwater); + mWater->setVisible(active); +} Water::~Water() { - Ogre::MeshManager::getSingleton().remove("water"); + MeshManager::getSingleton().remove("water"); mWaterNode->detachObject(mWater); mSceneManager->destroyEntity(mWater); mSceneManager->destroySceneNode(mWaterNode); - Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); + CompositorManager::getSingleton().removeCompositorChain(mViewport); } void Water::changeCell(const ESM::Cell* cell) @@ -65,31 +112,122 @@ void Water::setHeight(const float height) void Water::toggle() { - mWater->setVisible(!mWater->getVisible()); + if (mActive) + mWater->setVisible(!mWater->getVisible()); } void Water::checkUnderwater(float y) { - if ((mIsUnderwater && y > mTop) || !mWater->isVisible()) + if (!mActive) return; + if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID) { - try { - Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false); - } catch(...) {} + CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false); + + // tell the shader we are not underwater + Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0); + if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false)) + pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(0)); + + if (mReflectionTarget) + mReflectionTarget->setActive(mActive); + + mWater->setRenderQueueGroup(RQG_Water); + mIsUnderwater = false; } - if (!mIsUnderwater && y < mTop && mWater->isVisible()) + if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID) { - try { - Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", true); - } catch(...) {} + if (mUnderwaterEffect) + CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, true); + + // tell the shader we are underwater + Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0); + if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false)) + pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(1)); + + if (mReflectionTarget) + mReflectionTarget->setActive(false); + + mWater->setRenderQueueGroup(RQG_UnderWater); + mIsUnderwater = true; } } -Ogre::Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY) +Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY) { - return Ogre::Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2)); + return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2)); +} + +void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) +{ + if (evt.source == mReflectionTarget) + { + mWater->setVisible(false); + + // Some messy code to get the skybox to show up at all + // The problem here is that it gets clipped by the water plane + // Therefore scale it up a bit + Vector3 pos = mCamera->getRealPosition(); + pos.y = mTop*2 - pos.y; + mSky->setSkyPosition(pos); + mSky->scaleSky(mCamera->getFarClipDistance() / 1000.f); + + mCamera->enableCustomNearClipPlane(Plane(Vector3::UNIT_Y, mTop)); + mCamera->enableReflection(Plane(Vector3::UNIT_Y, mTop)); + } +} + +void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) +{ + mWater->setVisible(true); + + if (evt.source == mReflectionTarget) + { + mSky->resetSkyPosition(); + mSky->scaleSky(1); + mCamera->disableReflection(); + mCamera->disableCustomNearClipPlane(); + } +} + +void Water::createMaterial() +{ + mMaterial = MaterialManager::getSingleton().getByName("Water"); + + // these have to be set in code + std::string textureNames[32]; + for (int i=0; i<32; ++i) + { + textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds"; + } + mMaterial->getTechnique(1)->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2); + + // use technique without shaders if reflection is disabled + if (mReflectionTarget == 0) + mMaterial->removeTechnique(0); + + if (Settings::Manager::getBool("shader", "Water")) + { + CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor("gbuffer"); + + TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0); + TextureUnitState* tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap"); + if (tus != 0) + tus->setTexture(colorTexture); + + TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1); + tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("depthMap"); + if (tus != 0) + tus->setTexture(depthTexture); + } +} + +void Water::setViewportBackground(const ColourValue& bg) +{ + if (mReflectionTarget) + mReflectionTarget->getViewport(0)->setBackgroundColour(bg); } } // namespace diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 5a5d1cca09..0e23f5b0c3 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -4,10 +4,14 @@ #include #include +#include "renderconst.hpp" + namespace MWRender { + class SkyManager; + /// Water rendering - class Water : Ogre::RenderTargetListener, Ogre::Camera::Listener + class Water : public Ogre::RenderTargetListener { static const int CELL_SIZE = 8192; Ogre::Camera *mCamera; @@ -19,16 +23,37 @@ namespace MWRender { Ogre::Entity *mWater; bool mIsUnderwater; + bool mActive; int mTop; Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); + protected: + void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + + SkyManager* mSky; + + std::string mCompositorName; + + void createMaterial(); + Ogre::MaterialPtr mMaterial; + + Ogre::RenderTarget* mReflectionTarget; + + bool mUnderwaterEffect; + int mVisibilityFlags; + public: - Water (Ogre::Camera *camera, const ESM::Cell* cell); + Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell); ~Water(); + void setActive(bool active); + void toggle(); + void setViewportBackground(const Ogre::ColourValue& bg); + void checkUnderwater(float y); void changeCell(const ESM::Cell* cell); void setHeight(const float height); diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 7ff60a2035..df955ec198 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -127,4 +127,6 @@ op 0x2000141: GetWaterLevel op 0x2000142: SetWaterLevel op 0x2000143: ModWaterLevel op 0x2000144: ToggleWater, twa -opcodes 0x2000145-0x3ffffff unused +op 0x2000145: ToggleFogOfWar (tfow) +op 0x2000146: TogglePathgrid +opcodes 0x2000147-0x3ffffff unused diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 484c0d3ab5..426378efca 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -67,6 +67,19 @@ namespace MWScript } }; + class OpToggleFogOfWar : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + InterpreterContext& context = + static_cast (runtime.getContext()); + + context.getEnvironment().mWindowManager->toggleFogOfWar(); + } + }; + const int opcodeEnableBirthMenu = 0x200000e; const int opcodeEnableClassMenu = 0x200000f; const int opcodeEnableNameMenu = 0x2000010; @@ -79,6 +92,7 @@ namespace MWScript const int opcodeEnableRest = 0x2000017; const int opcodeShowRestMenu = 0x2000018; const int opcodeGetButtonPressed = 0x2000137; + const int opcodeToggleFogOfWar = 0x2000145; void registerExtensions (Compiler::Extensions& extensions) { @@ -100,6 +114,9 @@ namespace MWScript extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu); extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed); + + extensions.registerInstruction ("togglefogofwar", "", opcodeToggleFogOfWar); + extensions.registerInstruction ("tfow", "", opcodeToggleFogOfWar); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -135,6 +152,8 @@ namespace MWScript new OpShowDialogue (MWGui::GM_Rest)); interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed); + + interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar); } } } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 5109319ed0..a0770b9a88 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -106,7 +106,7 @@ namespace MWScript "Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off"); } }; - + class OpToggleWireframe : public Interpreter::Opcode0 { public: @@ -123,7 +123,23 @@ namespace MWScript "Wireframe Rendering -> On" : "Wireframe Rendering -> Off"); } }; - + + class OpTogglePathgrid : public Interpreter::Opcode0 + { + public: + virtual void execute (Interpreter::Runtime& runtime) + { + InterpreterContext& context = + static_cast (runtime.getContext()); + + bool enabled = + context.getWorld().toggleRenderMode (MWWorld::World::Render_Pathgrid); + + context.report (enabled ? + "Path Grid rendering -> On" : "Path Grid Rendering -> Off"); + } + }; + class OpFadeIn : public Interpreter::Opcode0 { public: @@ -135,11 +151,11 @@ namespace MWScript Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - + context.getWorld().getFader()->fadeIn(time); } }; - + class OpFadeOut : public Interpreter::Opcode0 { public: @@ -151,11 +167,11 @@ namespace MWScript Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - + context.getWorld().getFader()->fadeOut(time); } }; - + class OpFadeTo : public Interpreter::Opcode0 { public: @@ -167,10 +183,10 @@ namespace MWScript Interpreter::Type_Float alpha = runtime[0].mFloat; runtime.pop(); - + Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); - + context.getWorld().getFader()->fadeTo(alpha, time); } }; @@ -201,6 +217,7 @@ namespace MWScript const int opcodeFadeOut = 0x200013d; const int opcodeFadeTo = 0x200013e; const int opcodeToggleWater = 0x2000144; + const int opcodeTogglePathgrid = 0x2000146; void registerExtensions (Compiler::Extensions& extensions) { @@ -220,6 +237,8 @@ namespace MWScript extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo); extensions.registerInstruction ("togglewater", "", opcodeToggleWater); extensions.registerInstruction ("twa", "", opcodeToggleWater); + extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid); + extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -236,6 +255,7 @@ namespace MWScript interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn); interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut); interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo); + interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid); interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater); } } diff --git a/apps/openmw/mwsound/audiere_decoder.cpp b/apps/openmw/mwsound/audiere_decoder.cpp new file mode 100644 index 0000000000..acc2e5283c --- /dev/null +++ b/apps/openmw/mwsound/audiere_decoder.cpp @@ -0,0 +1,122 @@ +#ifdef OPENMW_USE_AUDIERE + +#include +#include + +#include "audiere_decoder.hpp" + + +static void fail(const std::string &msg) +{ throw std::runtime_error("Audiere exception: "+msg); } + +namespace MWSound +{ + +class OgreFile : public audiere::File +{ + Ogre::DataStreamPtr mStream; + + ADR_METHOD(int) read(void* buffer, int size) + { + return mStream->read(buffer, size); + } + + ADR_METHOD(bool) seek(int position, SeekMode mode) + { + if(mode == CURRENT) + mStream->seek(mStream->tell()+position); + else if(mode == BEGIN) + mStream->seek(position); + else if(mode == END) + mStream->seek(mStream->size()+position); + else + return false; + + return true; + } + + ADR_METHOD(int) tell() + { + return mStream->tell(); + } + + size_t refs; + virtual void ref() { ++refs; } + virtual void unref() + { + if(--refs == 0) + delete this; + } + +public: + OgreFile(const Ogre::DataStreamPtr &stream) + : mStream(stream), refs(1) + { } + virtual ~OgreFile() { } +}; + + +void Audiere_Decoder::open(const std::string &fname) +{ + close(); + + audiere::FilePtr file(new OgreFile(mResourceMgr.openResource(fname))); + mSoundSource = audiere::OpenSampleSource(file); + + int channels, srate; + audiere::SampleFormat format; + + mSoundSource->getFormat(channels, srate, format); + if(format == audiere::SF_S16) + mSampleType = SampleType_Int16; + else if(format == audiere::SF_U8) + mSampleType = SampleType_UInt8; + else + fail("Unsupported sample type"); + + if(channels == 1) + mChannelConfig = ChannelConfig_Mono; + else if(channels == 2) + mChannelConfig = ChannelConfig_Stereo; + else + fail("Unsupported channel count"); + + mSampleRate = srate; +} + +void Audiere_Decoder::close() +{ + mSoundSource = NULL; +} + +void Audiere_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) +{ + *samplerate = mSampleRate; + *chans = mChannelConfig; + *type = mSampleType; +} + +size_t Audiere_Decoder::read(char *buffer, size_t bytes) +{ + int size = bytesToFrames(bytes, mChannelConfig, mSampleType); + size = mSoundSource->read(size, buffer); + return framesToBytes(size, mChannelConfig, mSampleType); +} + +void Audiere_Decoder::rewind() +{ + mSoundSource->reset(); +} + +Audiere_Decoder::Audiere_Decoder() +{ +} + +Audiere_Decoder::~Audiere_Decoder() +{ + close(); +} + +} + +#endif diff --git a/apps/openmw/mwsound/audiere_decoder.hpp b/apps/openmw/mwsound/audiere_decoder.hpp new file mode 100644 index 0000000000..0ad026d515 --- /dev/null +++ b/apps/openmw/mwsound/audiere_decoder.hpp @@ -0,0 +1,42 @@ +#ifndef GAME_SOUND_AUDIERE_DECODER_H +#define GAME_SOUND_AUDIERE_DECODER_H + +#include + +#include "audiere.h" + +#include "sound_decoder.hpp" + + +namespace MWSound +{ + class Audiere_Decoder : public Sound_Decoder + { + audiere::SampleSourcePtr mSoundSource; + int mSampleRate; + SampleType mSampleType; + ChannelConfig mChannelConfig; + + virtual void open(const std::string &fname); + virtual void close(); + + virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type); + + virtual size_t read(char *buffer, size_t bytes); + virtual void rewind(); + + Audiere_Decoder& operator=(const Audiere_Decoder &rhs); + Audiere_Decoder(const Audiere_Decoder &rhs); + + Audiere_Decoder(); + public: + virtual ~Audiere_Decoder(); + + friend class SoundManager; + }; +#ifndef DEFAULT_DECODER +#define DEFAULT_DECODER (::MWSound::Audiere_Decoder) +#endif +}; + +#endif diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 610a797a2b..615def7019 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -467,10 +467,15 @@ void OpenAL_Output::init(const std::string &devname) else fail("Failed to open \""+devname+"\""); } - if(alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT")) - std::cout << "Opened \""< #include +#include #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" @@ -18,8 +19,8 @@ #include "openal_output.hpp" #define SOUND_OUT "OpenAL" -/* Set up the sound manager to use FFMPEG or MPG123+libsndfile for input. The - * OPENMW_USE_x macros are set in CMakeLists.txt. +/* Set up the sound manager to use FFMPEG, MPG123+libsndfile, or Audiere for + * input. The OPENMW_USE_x macros are set in CMakeLists.txt. */ #ifdef OPENMW_USE_FFMPEG #include "ffmpeg_decoder.hpp" @@ -28,6 +29,13 @@ #endif #endif +#ifdef OPENMW_USE_AUDIERE +#include "audiere_decoder.hpp" +#ifndef SOUND_IN +#define SOUND_IN "Audiere" +#endif +#endif + #ifdef OPENMW_USE_MPG123 #include "mpgsnd_decoder.hpp" #ifndef SOUND_IN @@ -42,11 +50,20 @@ namespace MWSound : mResourceMgr(Ogre::ResourceGroupManager::getSingleton()) , mEnvironment(environment) , mOutput(new DEFAULT_OUTPUT(*this)) - + , mMasterVolume(1.0f) + , mSFXVolume(1.0f) + , mMusicVolume(1.0f) { if(!useSound) return; + mMasterVolume = Settings::Manager::getFloat("master volume", "Sound"); + mMasterVolume = std::min(std::max(mMasterVolume, 0.0f), 1.0f); + mSFXVolume = Settings::Manager::getFloat("sfx volume", "Sound"); + mSFXVolume = std::min(std::max(mSFXVolume, 0.0f), 1.0f); + mMusicVolume = Settings::Manager::getFloat("music volume", "Sound"); + mMusicVolume = std::min(std::max(mMusicVolume, 0.0f), 1.0f); + std::cout << "Sound output: " << SOUND_OUT << std::endl; std::cout << "Sound decoder: " << SOUND_IN << std::endl; @@ -57,7 +74,19 @@ namespace MWSound for(size_t i = 0;i < names.size();i++) std::cout <<" "<init(); + std::string devname = Settings::Manager::getString("device", "Sound"); + try + { + mOutput->init(devname); + } + catch(std::exception &e) + { + if(devname.empty()) + throw; + std::cout <<"Failed to open device \""<init(); + Settings::Manager::setString("device", "Sound", ""); + } } catch(std::exception &e) { @@ -129,12 +158,15 @@ namespace MWSound void SoundManager::streamMusicFull(const std::string& filename) { + if(!mOutput->isInitialized()) + return; std::cout <<"Playing "<streamSound(filename, 0.4f, 1.0f, Play_NoEnv); - mMusic->mBaseVolume = 0.4f; + mMusic = mOutput->streamSound(filename, basevol, 1.0f, Play_NoEnv); + mMusic->mBaseVolume = basevol; mMusic->mFlags = Play_NoEnv; } catch(std::exception &e) @@ -173,10 +205,12 @@ namespace MWSound void SoundManager::say(MWWorld::Ptr ptr, const std::string& filename) { + if(!mOutput->isInitialized()) + return; try { // The range values are not tested - float basevol = 1.0f; /* TODO: volume settings */ + float basevol = mMasterVolume * mSFXVolume; std::string filePath = "Sound/"+filename; const ESM::Position &pos = ptr.getCellRef().pos; const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]); @@ -203,9 +237,11 @@ namespace MWSound SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, int mode) { SoundPtr sound; + if(!mOutput->isInitialized()) + return sound; try { - float basevol = 1.0f; /* TODO: volume settings */ + float basevol = mMasterVolume * mSFXVolume; float min, max; std::string file = lookup(soundId, basevol, min, max); @@ -230,10 +266,12 @@ namespace MWSound float volume, float pitch, int mode) { SoundPtr sound; + if(!mOutput->isInitialized()) + return sound; try { // Look up the sound in the ESM data - float basevol = 1.0f; /* TODO: volume settings */ + float basevol = mMasterVolume * mSFXVolume; float min, max; std::string file = lookup(soundId, basevol, min, max); const ESM::Position &pos = ptr.getCellRef().pos; @@ -407,7 +445,7 @@ namespace MWSound if(!isMusicPlaying()) startRandomTitle(); - MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell(); + const ESM::Cell *cell = mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell; Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera(); Ogre::Vector3 nPos, nDir, nUp; nPos = cam->getRealPosition(); @@ -415,7 +453,7 @@ namespace MWSound nUp = cam->getRealUp(); Environment env = Env_Normal; - if(nPos.y < current->cell->water) + if((cell->data.flags&cell->HasWater) && nPos.y < cell->water) env = Env_Underwater; // The output handler is expecting vectors oriented like the game @@ -443,6 +481,8 @@ namespace MWSound void SoundManager::update(float duration) { + if(!mOutput->isInitialized()) + return; updateSounds(duration); updateRegionSound(duration); } diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index cad5f61871..d64db299b4 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -56,6 +56,10 @@ namespace MWSound std::auto_ptr mOutput; + float mMasterVolume; + float mSFXVolume; + float mMusicVolume; + boost::shared_ptr mMusic; std::string mCurrentPlaylist; diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 9d766909f7..d3a0a34ae8 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -137,6 +137,11 @@ namespace MWWorld return -1; } + int Class::getValue (const Ptr& ptr) const + { + throw std::logic_error ("value not supported by this class"); + } + const Class& Class::get (const std::string& key) { std::map >::const_iterator iter = sClasses.find (key); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 67320b3e07..e474e9b926 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -155,6 +155,10 @@ namespace MWWorld /// no such skill. /// (default implementation: return -1) + virtual int getValue (const Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + /// (default implementation: throws an exception) + static const Class& get (const std::string& key); ///< If there is no class for this \a key, an exception is thrown. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index e64c9785f4..650418201b 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -4,8 +4,12 @@ #include #include +#include "../mwmechanics/npcstats.hpp" + #include "class.hpp" +#include /// \todo remove after rendering is implemented + void MWWorld::InventoryStore::copySlots (const InventoryStore& store) { // some const-trickery, required because of a flaw in the handling of MW-references and the @@ -24,10 +28,15 @@ void MWWorld::InventoryStore::copySlots (const InventoryStore& store) } } -MWWorld::InventoryStore::InventoryStore() +void MWWorld::InventoryStore::initSlots (TSlots& slots) { for (int i=0; i, bool> itemsSlots = + MWWorld::Class::get (*iter).getEquipmentSlots (*iter); + + for (std::vector::const_iterator iter2 (itemsSlots.first.begin()); + iter2!=itemsSlots.first.end(); ++iter2) + { + bool use = false; + + if (slots.at (*iter2)==end()) + use = true; // slot was empty before -> skill all further checks + else + { + Ptr old = *slots.at (*iter2); + + if (!use) + { + // check skill + int oldSkill = + MWWorld::Class::get (old).getEquipmentSkill (old, environment); + + if (testSkill!=-1 || oldSkill!=-1 || testSkill!=oldSkill) + { + if (stats.mSkill[oldSkill].getModified()>stats.mSkill[testSkill].getModified()) + continue; // rejected, because old item better matched the NPC's skills. + + if (stats.mSkill[oldSkill].getModified()= + MWWorld::Class::get (test).getValue (test)) + { + continue; + } + + use = true; + } + } + + /// \todo unstack, if reqquired (itemsSlots.second) + + slots[*iter2] = iter; + break; + } + } + + bool changed = false; + + for (std::size_t i=0; i mSlots; + typedef std::vector TSlots; + + mutable TSlots mSlots; void copySlots (const InventoryStore& store); + void initSlots (TSlots& slots); + public: InventoryStore(); @@ -52,6 +63,9 @@ namespace MWWorld ///< \note \a iteartor can be an end-iterator ContainerStoreIterator getSlot (int slot); + + void autoEquip (const MWMechanics::NpcStats& stats, const Environment& environment); + ///< Auto equip items according to stats and item value. }; } diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index c31c531223..d6e485f419 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -39,7 +39,7 @@ namespace MWWorld return mPtr.empty(); } - const std::type_info& getType() + const std::type_info& getType() const { assert (!mPtr.empty()); return mPtr.type(); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index df7d20bb60..2123b47999 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -204,7 +204,6 @@ namespace MWWorld mWorld->adjustSky(); mCellChanged = true; - mRendering.waterAdded(mCurrentCell); } //We need the ogre renderer and a scene node. @@ -257,8 +256,6 @@ namespace MWWorld mWorld->adjustSky(); mCellChanged = true; - - mRendering.waterAdded(cell); } void Scene::changeToExteriorCell (const ESM::Position& position) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 1972d8d5bc..fb0480171d 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -27,6 +27,9 @@ const float WeatherGlobals::mSunriseDuration = 2; const float WeatherGlobals::mSunsetDuration = 2; const float WeatherGlobals::mWeatherUpdateTime = 20.f; + +// morrowind sets these per-weather, but since they are only used by 'thunderstorm' +// weather setting anyway, we can just as well set them globally const float WeatherGlobals::mThunderFrequency = .4; const float WeatherGlobals::mThunderThreshold = 0.6; const float WeatherGlobals::mThunderSoundDelay = 0.25; @@ -268,7 +271,8 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E blight.mGlareView = 0; blight.mAmbientLoopSoundID = "blight"; mWeatherSettings["blight"] = blight; - + + /* Weather snow; snow.mCloudTexture = "tx_bm_sky_snow.dds"; snow.mCloudsMaximumPercent = 1.0; @@ -325,18 +329,21 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::E blizzard.mGlareView = 0; blizzard.mAmbientLoopSoundID = "BM Blizzard"; mWeatherSettings["blizzard"] = blizzard; + */ } void WeatherManager::setWeather(const String& weather, bool instant) { - if (weather == mCurrentWeather && mNextWeather == "") + if (weather == mCurrentWeather && mNextWeather == "") + { + mFirstUpdate = false; return; + } if (instant || mFirstUpdate) { mNextWeather = ""; mCurrentWeather = weather; - mFirstUpdate = false; } else { @@ -350,6 +357,7 @@ void WeatherManager::setWeather(const String& weather, bool instant) mNextWeather = weather; mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600; } + mFirstUpdate = false; } WeatherResult WeatherManager::getResult(const String& weather) @@ -467,6 +475,7 @@ WeatherResult WeatherManager::transition(float factor) result.mCloudSpeed = current.mCloudSpeed; result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity); result.mGlareView = lerp(current.mGlareView, other.mGlareView); + result.mNightFade = lerp(current.mNightFade, other.mNightFade); result.mNight = current.mNight; @@ -506,20 +515,20 @@ void WeatherManager::update(float duration) float thunder = region->data.thunder/255.f; float ash = region->data.ash/255.f; float blight = region->data.blight/255.f; - float snow = region->data.a/255.f; - float blizzard = region->data.b/255.f; + //float snow = region->data.a/255.f; + //float blizzard = region->data.b/255.f; // re-scale to 100 percent - const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard; + const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight;//+snow+blizzard; srand(time(NULL)); float random = ((rand()%100)/100.f) * total; - if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) - weather = "blizzard"; - else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear) - weather = "snow"; - else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear) + //if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) + // weather = "blizzard"; + //else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear) + // weather = "snow"; + /*else*/ if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear) weather = "blight"; else if (random >= thunder+rain+overcast+foggy+cloudy+clear) weather = "ashstorm"; @@ -579,8 +588,8 @@ void WeatherManager::update(float duration) int facing = (mHour > 13.f) ? 1 : -1; Vector3 final( - (1-height)*facing, - (1-height)*facing, + -(1-height)*facing, + -(1-height)*facing, height); mRendering->setSunDirection(final); diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index a7252353dd..1c64039d4c 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -152,10 +152,30 @@ namespace MWWorld mRendering->skyDisable(); } + void World::setFallbackValues(std::map fallbackMap) + { + mFallback = fallbackMap; + } + + std::string World::getFallback(std::string key) + { + return getFallback(key, ""); + } + + std::string World::getFallback(std::string key, std::string def) + { + std::map::iterator it; + if((it = mFallback.find(key)) == mFallback.end()) + { + return def; + } + return it->second; + } + World::World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, const std::string& master, const boost::filesystem::path& resDir, - bool newGame, Environment& environment, const std::string& encoding) + bool newGame, Environment& environment, const std::string& encoding, std::map fallbackMap) : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), mSky (true), mEnvironment (environment), mNextDynamicRecord (0), mCells (mStore, mEsm, *this), mNumFacing(0) @@ -191,6 +211,8 @@ namespace MWWorld mWorldScene = new Scene(environment, this, *mRendering, mPhysics); + setFallbackValues(fallbackMap); + } diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 92540f82b7..8dd370ad76 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -100,6 +100,7 @@ namespace MWWorld std::string mFaced1Name; std::string mFaced2Name; int mNumFacing; + std::map mFallback; int getDaysPerMonth (int month) const; @@ -110,7 +111,7 @@ namespace MWWorld World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, const std::string& master, const boost::filesystem::path& resDir, bool newGame, - Environment& environment, const std::string& encoding); + Environment& environment, const std::string& encoding, std::map fallbackMap); ~World(); @@ -125,6 +126,12 @@ namespace MWWorld void adjustSky(); + void setFallbackValues(std::map fallbackMap); + + std::string getFallback(std::string key); + + std::string getFallback(std::string key, std::string def); + MWWorld::Player& getPlayer(); const ESMS::ESMStore& getStore() const; diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index cc97992084..6731d584c0 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -82,20 +82,37 @@ findpkg_finish ( "MYGUI" ) ELSE (WIN32) #Unix CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR) FIND_PACKAGE(PkgConfig) - PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI) - IF (MYGUI_INCLUDE_DIRS) - SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) - SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) - SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - ELSE (MYGUI_INCLUDE_DIRS) - FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) - FIND_LIBRARY(MYGUI_LIBRARIES mygui PATHS /usr/lib /usr/local/lib) - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) - STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") - STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") - ENDIF (MYGUI_INCLUDE_DIRS) + IF(MYGUI_STATIC) + PKG_SEARCH_MODULE(MYGUI MYGUIStatic MyGUIStatic) + IF (MYGUI_INCLUDE_DIRS) + SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) + SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) + SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + ELSE (MYGUI_INCLUDE_DIRS) + FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) + FIND_LIBRARY(MYGUI_LIBRARIES myguistatic PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) + STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") + STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") + ENDIF (MYGUI_INCLUDE_DIRS) + ELSE(MYGUI_STATIC) + PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI) + IF (MYGUI_INCLUDE_DIRS) + SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) + SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) + SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + ELSE (MYGUI_INCLUDE_DIRS) + FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) + FIND_LIBRARY(MYGUI_LIBRARIES mygui PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) + STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") + STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") + ENDIF (MYGUI_INCLUDE_DIRS) + ENDIF(MYGUI_STATIC) ENDIF (WIN32) #Do some preparation diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index c95efb37df..b48c50640c 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -2,6 +2,10 @@ project (Components) # source files +add_component_dir (settings + settings + ) + add_component_dir (bsa bsa_archive bsa_file ) diff --git a/components/compiler/parser.cpp b/components/compiler/parser.cpp index 73cadfeba1..90368eee01 100644 --- a/components/compiler/parser.cpp +++ b/components/compiler/parser.cpp @@ -7,6 +7,7 @@ #include "errorhandler.hpp" #include "exception.hpp" +#include "scanner.hpp" namespace Compiler { @@ -81,6 +82,8 @@ namespace Compiler { if (!(mOptional && mEmpty)) reportSeriousError ("Unexpected numeric value", loc); + else + scanner.putbackInt (value, loc); return false; } @@ -94,6 +97,8 @@ namespace Compiler { if (!(mOptional && mEmpty)) reportSeriousError ("Unexpected floating point value", loc); + else + scanner.putbackFloat (value, loc); return false; } @@ -108,6 +113,8 @@ namespace Compiler { if (!(mOptional && mEmpty)) reportSeriousError ("Unexpected name", loc); + else + scanner.putbackName (name, loc); return false; } @@ -121,6 +128,8 @@ namespace Compiler { if (!(mOptional && mEmpty)) reportSeriousError ("Unexpected keyword", loc); + else + scanner.putbackKeyword (keyword, loc); return false; } @@ -134,6 +143,8 @@ namespace Compiler { if (!(mOptional && mEmpty)) reportSeriousError ("Unexpected special token", loc); + else + scanner.putbackSpecial (code, loc); return false; } diff --git a/components/compiler/stringparser.cpp b/components/compiler/stringparser.cpp index fe7bd30b9e..396a88c786 100644 --- a/components/compiler/stringparser.cpp +++ b/components/compiler/stringparser.cpp @@ -39,11 +39,6 @@ namespace Compiler mState = CommaState; return true; } - else if (code==Scanner::S_newline && mState==StartState) - { - scanner.putbackSpecial (code, loc); - return false; - } return Parser::parseSpecial (code, loc, scanner); } diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index cd2cf1d917..96afdf8316 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -2,6 +2,24 @@ namespace ESM { + +Land::Land() + : flags(0) + , X(0) + , Y(0) + , mEsm(NULL) + , hasData(false) + , dataLoaded(false) + , landData(NULL) +{ +} + +Land::~Land() +{ + delete landData; +} + + void Land::load(ESMReader &esm) { mEsm = &esm; diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index 5ccd966d92..ebc314a280 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -11,6 +11,9 @@ namespace ESM struct Land { + Land(); + ~Land(); + int flags; // Only first four bits seem to be used, don't know what // they mean. int X, Y; // Map coordinates. @@ -77,6 +80,11 @@ struct Land * Frees memory allocated for land data */ void unloadData(); + + private: + Land(const Land& land); + Land& operator=(const Land& land); }; + } #endif diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 16d37bec71..d7a4100aae 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -457,7 +457,7 @@ namespace ESMS } } - Pathgrid *find(int cellX, int cellY, std::string cellName) const + Pathgrid *find(int cellX, int cellY, const std::string &cellName) const { Pathgrid *result = search(cellX, cellY, cellName); if (!result) @@ -467,7 +467,7 @@ namespace ESMS return result; } - Pathgrid *search(int cellX, int cellY, std::string cellName) const + Pathgrid *search(int cellX, int cellY, const std::string &cellName) const { Pathgrid *result = NULL; if (cellX == 0 && cellY == 0) // possibly interior diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 616dd1daf9..3e48bb3b2c 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -25,6 +25,7 @@ #include "ogre_nif_loader.hpp" +#include typedef unsigned char ubyte; @@ -299,138 +300,150 @@ void NIFLoader::createMaterial(const String &name, material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]); material->setShininess(glossiness); - // Create shader for the material - // vertex - HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); - - HighLevelGpuProgramPtr vertex; - if (mgr.getByName("main_vp").isNull()) + if (Settings::Manager::getBool("shaders", "Objects")) { - vertex = mgr.createProgram("main_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "cg", GPT_VERTEX_PROGRAM); - vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1"); - vertex->setParameter("entry_point", "main_vp"); - StringUtil::StrStreamType outStream; - outStream << - "void main_vp( \n" - " float4 position : POSITION, \n" - " float4 normal : NORMAL, \n" - " float4 colour : COLOR, \n" - " in float2 uv : TEXCOORD0, \n" - " out float2 oUV : TEXCOORD0, \n" - " out float4 oPosition : POSITION, \n" - " out float4 oPositionObjSpace : TEXCOORD1, \n" - " out float4 oNormal : TEXCOORD2, \n" - " out float oFogValue : TEXCOORD3, \n" - " out float4 oVertexColour : TEXCOORD4, \n" - " uniform float4 fogParams, \n" - " uniform float4x4 worldViewProj \n" - ") \n" - "{ \n" - " oVertexColour = colour; \n" - " oUV = uv; \n" - " oNormal = normal; \n" - " oPosition = mul( worldViewProj, position ); \n" - " oFogValue = saturate((oPosition.z - fogParams.y) * fogParams.w); \n" - " oPositionObjSpace = position; \n" - "}"; - vertex->setSource(outStream.str()); - vertex->load(); - vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); - vertex->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); - } - else - vertex = mgr.getByName("main_vp"); - material->getTechnique(0)->getPass(0)->setVertexProgram(vertex->getName()); + bool mrt = Settings::Manager::getBool("shader", "Water"); - // the number of lights to support. - // when rendering an object, OGRE automatically picks the lights that are - // closest to the object being rendered. unfortunately this mechanism does - // not work perfectly for objects batched together (they will all use the same - // lights). to work around this, we are simply pushing the maximum number - // of lights here in order to minimize disappearing lights. - float num_lights; - if (GpuProgramManager::getSingleton().isSyntaxSupported("fp40") || - GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0")) - num_lights = 8 /* 32 */; - else - num_lights = 8; + // Create shader for the material + // vertex + HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); - // fragment - HighLevelGpuProgramPtr fragment; - if (mgr.getByName("main_fp").isNull()) - { - fragment = mgr.createProgram("main_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "cg", GPT_FRAGMENT_PROGRAM); - fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1"); - fragment->setParameter("entry_point", "main_fp"); - StringUtil::StrStreamType outStream; - outStream << - "void main_fp( \n" - " in float2 uv : TEXCOORD0, \n" - " out float4 oColor : COLOR, \n" - " uniform sampler2D texture : TEXUNIT0, \n" - " float4 positionObjSpace : TEXCOORD1, \n" - " float4 normal : TEXCOORD2, \n" - " float fogValue : TEXCOORD3, \n" - " float4 vertexColour : TEXCOORD4, \n" - " uniform float4 fogColour, \n"; - - for (int i=0; isetParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1"); + vertex->setParameter("entry_point", "main_vp"); + StringUtil::StrStreamType outStream; outStream << - " uniform float4 lightDiffuse"<setSource(outStream.str()); + vertex->load(); + vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); } - outStream << - " uniform float4 lightAmbient, \n" - " uniform float4 ambient, \n" - " uniform float4 diffuse, \n" - " uniform float4 emissive \n" - ") \n" - "{ \n" - " float4 tex = tex2D(texture, uv); \n" - " float d; \n" - " float attn; \n" - " float3 lightColour = float3(0, 0, 0); \n"; - - for (int i=0; igetTechnique(0)->getPass(0)->setVertexProgram(vertex->getName()); + + // the number of lights to support. + // when rendering an object, OGRE automatically picks the lights that are + // closest to the object being rendered. unfortunately this mechanism does + // not work perfectly for objects batched together (they will all use the same + // lights). to work around this, we are simply pushing the maximum number + // of lights here in order to minimize disappearing lights. + int num_lights = Settings::Manager::getInt("num lights", "Objects"); + + // fragment + HighLevelGpuProgramPtr fragment; + if (mgr.getByName("main_fp").isNull()) { + fragment = mgr.createProgram("main_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "cg", GPT_FRAGMENT_PROGRAM); + fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1"); + fragment->setParameter("entry_point", "main_fp"); + StringUtil::StrStreamType outStream; outStream << - " float3 lightDir"<setSource(outStream.str()); + fragment->load(); + + for (int i=0; igetDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); + fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); + fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); + } + fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); + if (mrt) + fragment->getDefaultParameters()->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE); } - - outStream << - " float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n" - " oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n" - " oColor.a = tex.a * diffuse.a * vertexColour.a; \n" - "}"; - fragment->setSource(outStream.str()); - fragment->load(); - - for (int i=0; igetDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); - fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); - fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); - } - fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); + else + fragment = mgr.getByName("main_fp"); + material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName()); } - else - fragment = mgr.getByName("main_fp"); - material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName()); } // Takes a name and adds a unique part to it. This is just used to diff --git a/components/settings/settings.cpp b/components/settings/settings.cpp new file mode 100644 index 0000000000..28201eda2a --- /dev/null +++ b/components/settings/settings.cpp @@ -0,0 +1,158 @@ +#include "settings.hpp" + +#include + +#include +#include + +using namespace Settings; + +Ogre::ConfigFile Manager::mFile = Ogre::ConfigFile(); +Ogre::ConfigFile Manager::mDefaultFile = Ogre::ConfigFile(); +CategorySettingVector Manager::mChangedSettings = CategorySettingVector(); +CategorySettingValueMap Manager::mNewSettings = CategorySettingValueMap(); + +void Manager::loadUser (const std::string& file) +{ + mFile.load(file); +} + +void Manager::loadDefault (const std::string& file) +{ + mDefaultFile.load(file); +} + +void Manager::saveUser(const std::string& file) +{ + std::fstream fout(file.c_str(), std::ios::out); + + Ogre::ConfigFile::SectionIterator seci = mFile.getSectionIterator(); + + while (seci.hasMoreElements()) + { + Ogre::String sectionName = seci.peekNextKey(); + + if (sectionName.length() > 0) + fout << '\n' << '[' << seci.peekNextKey() << ']' << '\n'; + + Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); + Ogre::ConfigFile::SettingsMultiMap::iterator i; + for (i = settings->begin(); i != settings->end(); ++i) + { + fout << i->first.c_str() << " = " << i->second.c_str() << '\n'; + } + + CategorySettingValueMap::iterator it = mNewSettings.begin(); + while (it != mNewSettings.end()) + { + if (it->first.first == sectionName) + { + fout << it->first.second << " = " << it->second << '\n'; + mNewSettings.erase(it++); + } + else + ++it; + } + } + + std::string category = ""; + for (CategorySettingValueMap::iterator it = mNewSettings.begin(); + it != mNewSettings.end(); ++it) + { + if (category != it->first.first) + { + category = it->first.first; + fout << '\n' << '[' << category << ']' << '\n'; + } + fout << it->first.second << " = " << it->second << '\n'; + } +} + +const std::string Manager::getString (const std::string& setting, const std::string& category) +{ + if (mNewSettings.find(std::make_pair(category, setting)) != mNewSettings.end()) + return mNewSettings[std::make_pair(category, setting)]; + + std::string defaultval = mDefaultFile.getSetting(setting, category); + return mFile.getSetting(setting, category, defaultval); +} + +const float Manager::getFloat (const std::string& setting, const std::string& category) +{ + return Ogre::StringConverter::parseReal( getString(setting, category) ); +} + +const int Manager::getInt (const std::string& setting, const std::string& category) +{ + return Ogre::StringConverter::parseInt( getString(setting, category) ); +} + +const bool Manager::getBool (const std::string& setting, const std::string& category) +{ + return Ogre::StringConverter::parseBool( getString(setting, category) ); +} + +void Manager::setString (const std::string& setting, const std::string& category, const std::string& value) +{ + CategorySetting s = std::make_pair(category, setting); + + bool found=false; + try + { + Ogre::ConfigFile::SettingsIterator it = mFile.getSettingsIterator(category); + while (it.hasMoreElements()) + { + Ogre::ConfigFile::SettingsMultiMap::iterator i = it.current(); + + if ((*i).first == setting) + { + if ((*i).second != value) + { + mChangedSettings.push_back(std::make_pair(category, setting)); + (*i).second = value; + } + found = true; + } + + it.getNext(); + } + } + catch (Ogre::Exception&) + {} + + if (!found) + { + if (mNewSettings.find(s) != mNewSettings.end()) + { + if (mNewSettings[s] != value) + { + mChangedSettings.push_back(std::make_pair(category, setting)); + mNewSettings[s] = value; + } + } + else + mNewSettings[s] = value; + } +} + +void Manager::setInt (const std::string& setting, const std::string& category, const int value) +{ + setString(setting, category, Ogre::StringConverter::toString(value)); +} + +void Manager::setFloat (const std::string& setting, const std::string& category, const float value) +{ + setString(setting, category, Ogre::StringConverter::toString(value)); +} + +void Manager::setBool (const std::string& setting, const std::string& category, const bool value) +{ + setString(setting, category, Ogre::StringConverter::toString(value)); +} + +const CategorySettingVector Manager::apply() +{ + CategorySettingVector vec = mChangedSettings; + mChangedSettings.clear(); + return vec; +} diff --git a/components/settings/settings.hpp b/components/settings/settings.hpp new file mode 100644 index 0000000000..e9858eb945 --- /dev/null +++ b/components/settings/settings.hpp @@ -0,0 +1,52 @@ +#ifndef _COMPONENTS_SETTINGS_H +#define _COMPONENTS_SETTINGS_H + +#include + +namespace Settings +{ + typedef std::pair < std::string, std::string > CategorySetting; + typedef std::vector< std::pair > CategorySettingVector; + typedef std::map < CategorySetting, std::string > CategorySettingValueMap; + + /// + /// \brief Settings management (can change during runtime) + /// + class Manager + { + public: + static Ogre::ConfigFile mFile; + static Ogre::ConfigFile mDefaultFile; + + static CategorySettingVector mChangedSettings; + ///< tracks all the settings that were changed since the last apply() call + + static CategorySettingValueMap mNewSettings; + ///< tracks all the settings that are in the default file, but not in user file yet + + void loadDefault (const std::string& file); + ///< load file as the default settings (can be overridden by user settings) + + void loadUser (const std::string& file); + ///< load file as user settings + + void saveUser (const std::string& file); + ///< save user settings to file + + static const CategorySettingVector apply(); + ///< returns the list of changed settings and then clears it + + static const int getInt (const std::string& setting, const std::string& category); + static const float getFloat (const std::string& setting, const std::string& category); + static const std::string getString (const std::string& setting, const std::string& category); + static const bool getBool (const std::string& setting, const std::string& category); + + static void setInt (const std::string& setting, const std::string& category, const int value); + static void setFloat (const std::string& setting, const std::string& category, const float value); + static void setString (const std::string& setting, const std::string& category, const std::string& value); + static void setBool (const std::string& setting, const std::string& category, const bool value); + }; + +} + +#endif // _COMPONENTS_SETTINGS_H diff --git a/components/to_utf8/gen_iconv.cpp b/components/to_utf8/gen_iconv.cpp index 6202052455..b7298e304a 100644 --- a/components/to_utf8/gen_iconv.cpp +++ b/components/to_utf8/gen_iconv.cpp @@ -12,7 +12,7 @@ void tab() { cout << " "; } // write one number with a space in front of it and a comma after it void num(unsigned char i, bool last) { - cout << " 0x" << (unsigned)i; + cout << " (char)0x" << (unsigned)i; if(!last) cout << ","; } diff --git a/components/to_utf8/tables_gen.hpp b/components/to_utf8/tables_gen.hpp index 79945bddca..1084ca28f9 100644 --- a/components/to_utf8/tables_gen.hpp +++ b/components/to_utf8/tables_gen.hpp @@ -10,785 +10,785 @@ namespace ToUTF8 /// Serbian (Latin script), Romanian and Albanian. static char windows_1250[] = { - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x8, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x9, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xa, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xb, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xf, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x14, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x15, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x16, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x17, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x18, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x19, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x22, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x23, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x24, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x25, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x26, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x27, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x28, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x29, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x32, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x33, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x34, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x35, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x36, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x38, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x39, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x41, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x42, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x43, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x44, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x45, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x46, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x47, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x48, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x49, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x51, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x52, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x53, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x54, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x55, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x56, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x57, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x58, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x59, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x61, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x62, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x63, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x64, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x65, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x66, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x67, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x68, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x69, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x71, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x72, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x73, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x74, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x75, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x76, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x77, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x78, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x79, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7f, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x82, 0xac, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x3, 0xe2, 0x80, 0x9a, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x3, 0xe2, 0x80, 0x9e, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa6, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa1, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x3, 0xe2, 0x80, 0xb0, 0x0, 0x0, - 0x2, 0xc5, 0xa0, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xb9, 0x0, 0x0, - 0x2, 0xc5, 0x9a, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xa4, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xbd, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xb9, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x3, 0xe2, 0x80, 0x98, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x99, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9c, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9d, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa2, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x93, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x94, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x3, 0xe2, 0x84, 0xa2, 0x0, 0x0, - 0x2, 0xc5, 0xa1, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xba, 0x0, 0x0, - 0x2, 0xc5, 0x9b, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xa5, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xbe, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xba, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa0, 0x0, 0x0, 0x0, - 0x2, 0xcb, 0x87, 0x0, 0x0, 0x0, - 0x2, 0xcb, 0x98, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x81, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa4, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x84, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa6, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa7, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa8, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa9, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x9e, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xab, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xac, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xad, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xae, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xbb, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb0, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb1, 0x0, 0x0, 0x0, - 0x2, 0xcb, 0x9b, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x82, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb4, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb5, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb6, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb7, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb8, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x85, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x9f, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xbb, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0xbd, 0x0, 0x0, 0x0, - 0x2, 0xcb, 0x9d, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0xbe, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xbc, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x94, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x81, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x82, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x82, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x84, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0xb9, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x86, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x87, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x8c, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x89, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x98, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8b, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x9a, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8d, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8e, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x8e, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x90, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x83, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x87, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x93, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x94, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x90, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x96, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x97, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x98, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xae, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9a, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xb0, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9c, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9d, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xa2, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9f, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x95, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa1, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa2, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x83, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa4, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0xba, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x87, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa7, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x8d, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa9, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x99, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xab, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x9b, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xad, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xae, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x8f, 0x0, 0x0, 0x0, - 0x2, 0xc4, 0x91, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x84, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x88, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb3, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb4, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x91, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb6, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb7, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0x99, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xaf, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xba, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xb1, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xbc, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xbd, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xa3, 0x0, 0x0, 0x0, - 0x2, 0xcb, 0x99, 0x0, 0x0, 0x0 + (char)0x1, (char)0x0, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x8, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x9, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xa, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xb, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xc, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xd, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xe, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xf, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x10, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x11, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x12, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x13, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x14, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x15, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x16, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x17, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x18, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x19, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x21, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x22, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x23, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x24, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x25, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x26, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x27, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x28, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x29, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x30, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x31, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x32, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x33, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x34, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x35, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x36, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x37, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x38, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x39, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x40, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x41, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x42, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x43, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x44, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x45, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x46, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x47, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x48, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x49, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x50, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x51, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x52, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x53, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x54, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x55, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x56, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x57, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x58, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x59, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x60, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x61, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x62, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x63, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x64, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x65, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x66, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x67, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x68, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x69, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x70, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x71, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x72, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x73, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x74, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x75, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x76, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x77, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x78, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x79, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x82, (char)0xac, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x3, (char)0xe2, (char)0x80, (char)0x9a, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x3, (char)0xe2, (char)0x80, (char)0x9e, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa6, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa1, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x3, (char)0xe2, (char)0x80, (char)0xb0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xa0, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xb9, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x9a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xa4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xbd, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xb9, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x3, (char)0xe2, (char)0x80, (char)0x98, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x99, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9c, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9d, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa2, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x93, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x94, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x3, (char)0xe2, (char)0x84, (char)0xa2, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xa1, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xba, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x9b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xa5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xbe, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xba, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xcb, (char)0x87, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xcb, (char)0x98, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x81, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x84, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x9e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xab, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xac, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xad, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xae, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xbb, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xcb, (char)0x9b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x82, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x85, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x9f, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xbb, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0xbd, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xcb, (char)0x9d, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0xbe, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xbc, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x94, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x81, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x82, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x82, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x84, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0xb9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x86, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x87, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x8c, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x89, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x98, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x9a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8d, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x8e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x90, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x83, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x87, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x93, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x94, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x90, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x96, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x97, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x98, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xae, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xb0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9c, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9d, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xa2, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9f, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x95, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa2, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x83, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0xba, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x87, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x8d, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x99, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xab, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x9b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xad, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xae, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x8f, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc4, (char)0x91, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x84, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x88, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb3, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x91, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x99, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xaf, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xba, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xb1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xbc, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xbd, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xa3, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xcb, (char)0x99, (char)0x0, (char)0x0, (char)0x0 }; /// Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic /// and other languages static char windows_1251[] = { - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x8, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x9, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xa, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xb, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xf, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x14, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x15, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x16, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x17, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x18, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x19, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x22, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x23, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x24, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x25, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x26, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x27, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x28, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x29, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x32, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x33, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x34, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x35, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x36, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x38, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x39, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x41, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x42, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x43, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x44, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x45, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x46, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x47, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x48, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x49, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x51, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x52, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x53, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x54, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x55, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x56, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x57, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x58, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x59, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x61, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x62, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x63, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x64, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x65, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x66, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x67, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x68, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x69, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x71, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x72, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x73, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x74, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x75, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x76, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x77, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x78, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x79, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7f, 0x0, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x82, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x83, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9a, 0x0, 0x0, - 0x2, 0xd1, 0x93, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9e, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa6, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa1, 0x0, 0x0, - 0x3, 0xe2, 0x82, 0xac, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xb0, 0x0, 0x0, - 0x2, 0xd0, 0x89, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xb9, 0x0, 0x0, - 0x2, 0xd0, 0x8a, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x8c, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x8b, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x8f, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x92, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x98, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x99, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9c, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9d, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa2, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x93, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x94, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x3, 0xe2, 0x84, 0xa2, 0x0, 0x0, - 0x2, 0xd1, 0x99, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xba, 0x0, 0x0, - 0x2, 0xd1, 0x9a, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x9c, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x9b, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x9f, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa0, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x8e, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x9e, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x88, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa4, 0x0, 0x0, 0x0, - 0x2, 0xd2, 0x90, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa6, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa7, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x81, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa9, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x84, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xab, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xac, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xad, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xae, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x87, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb0, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb1, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x86, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x96, 0x0, 0x0, 0x0, - 0x2, 0xd2, 0x91, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb5, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb6, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb7, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x91, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x84, 0x96, 0x0, 0x0, - 0x2, 0xd1, 0x94, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xbb, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x98, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x85, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x95, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x97, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x90, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x91, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x92, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x93, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x94, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x95, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x96, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x97, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x98, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x99, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x9a, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x9b, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x9c, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x9d, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x9e, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0x9f, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa0, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa1, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa2, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa3, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa4, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa5, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa6, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa7, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa8, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xa9, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xaa, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xab, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xac, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xad, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xae, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xaf, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb0, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb1, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb2, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb3, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb4, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb5, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb6, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb7, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb8, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xb9, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xba, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xbb, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xbc, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xbd, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xbe, 0x0, 0x0, 0x0, - 0x2, 0xd0, 0xbf, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x80, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x81, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x82, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x83, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x84, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x85, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x86, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x87, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x88, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x89, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x8a, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x8b, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x8c, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x8d, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x8e, 0x0, 0x0, 0x0, - 0x2, 0xd1, 0x8f, 0x0, 0x0, 0x0 + (char)0x1, (char)0x0, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x8, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x9, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xa, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xb, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xc, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xd, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xe, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xf, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x10, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x11, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x12, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x13, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x14, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x15, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x16, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x17, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x18, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x19, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x21, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x22, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x23, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x24, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x25, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x26, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x27, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x28, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x29, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x30, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x31, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x32, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x33, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x34, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x35, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x36, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x37, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x38, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x39, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x40, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x41, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x42, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x43, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x44, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x45, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x46, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x47, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x48, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x49, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x50, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x51, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x52, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x53, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x54, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x55, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x56, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x57, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x58, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x59, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x60, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x61, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x62, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x63, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x64, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x65, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x66, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x67, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x68, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x69, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x70, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x71, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x72, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x73, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x74, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x75, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x76, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x77, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x78, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x79, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x82, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x83, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9a, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x93, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9e, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa6, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa1, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x82, (char)0xac, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xb0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x89, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xb9, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x8a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x8c, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x8b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x8f, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x92, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x98, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x99, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9c, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9d, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa2, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x93, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x94, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x3, (char)0xe2, (char)0x84, (char)0xa2, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x99, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xba, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x9a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x9c, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x9b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x9f, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x8e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x9e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x88, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd2, (char)0x90, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x81, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x84, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xab, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xac, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xad, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xae, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x87, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x86, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x96, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd2, (char)0x91, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x91, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x84, (char)0x96, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x94, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xbb, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x98, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x85, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x95, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x97, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x90, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x91, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x92, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x93, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x94, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x95, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x96, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x97, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x98, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x99, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x9a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x9b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x9c, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x9d, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x9e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0x9f, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa2, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa3, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xa9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xaa, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xab, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xac, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xad, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xae, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xaf, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb2, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb3, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xb9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xba, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xbb, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xbc, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xbd, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xbe, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd0, (char)0xbf, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x80, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x81, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x82, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x83, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x84, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x85, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x86, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x87, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x88, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x89, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x8a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x8b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x8c, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x8d, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x8e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xd1, (char)0x8f, (char)0x0, (char)0x0, (char)0x0 }; /// Latin alphabet used by English and some other Western languages static char windows_1252[] = { - 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x8, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x9, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xa, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xb, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xc, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xd, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xe, 0x0, 0x0, 0x0, 0x0, - 0x1, 0xf, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x11, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x12, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x13, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x14, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x15, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x16, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x17, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x18, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x19, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x21, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x22, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x23, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x24, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x25, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x26, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x27, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x28, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x29, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x2f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x31, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x32, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x33, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x34, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x35, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x36, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x38, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x39, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x3f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x41, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x42, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x43, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x44, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x45, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x46, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x47, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x48, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x49, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x4f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x50, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x51, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x52, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x53, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x54, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x55, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x56, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x57, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x58, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x59, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x5f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x60, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x61, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x62, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x63, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x64, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x65, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x66, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x67, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x68, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x69, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x6f, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x70, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x71, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x72, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x73, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x74, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x75, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x76, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x77, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x78, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x79, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7a, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7b, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7c, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7d, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7e, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x7f, 0x0, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x82, 0xac, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x3, 0xe2, 0x80, 0x9a, 0x0, 0x0, - 0x2, 0xc6, 0x92, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9e, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa6, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa1, 0x0, 0x0, - 0x2, 0xcb, 0x86, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xb0, 0x0, 0x0, - 0x2, 0xc5, 0xa0, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xb9, 0x0, 0x0, - 0x2, 0xc5, 0x92, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x2, 0xc5, 0xbd, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x3, 0xe2, 0x80, 0x98, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x99, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9c, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x9d, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xa2, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x93, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0x94, 0x0, 0x0, - 0x2, 0xcb, 0x9c, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x84, 0xa2, 0x0, 0x0, - 0x2, 0xc5, 0xa1, 0x0, 0x0, 0x0, - 0x3, 0xe2, 0x80, 0xba, 0x0, 0x0, - 0x2, 0xc5, 0x93, 0x0, 0x0, 0x0, - 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, // not part of this charset - 0x2, 0xc5, 0xbe, 0x0, 0x0, 0x0, - 0x2, 0xc5, 0xb8, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa0, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa1, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa2, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa3, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa4, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa5, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa6, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa7, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa8, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xa9, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xaa, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xab, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xac, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xad, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xae, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xaf, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb0, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb1, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb2, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb3, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb4, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb5, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb6, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb7, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb8, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xb9, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xba, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xbb, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xbc, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xbd, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xbe, 0x0, 0x0, 0x0, - 0x2, 0xc2, 0xbf, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x80, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x81, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x82, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x83, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x84, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x85, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x86, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x87, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x88, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x89, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8a, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8b, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8c, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8d, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8e, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x8f, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x90, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x91, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x92, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x93, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x94, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x95, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x96, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x97, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x98, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x99, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9a, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9b, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9c, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9d, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9e, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0x9f, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa0, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa1, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa2, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa3, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa4, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa5, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa6, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa7, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa8, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xa9, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xaa, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xab, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xac, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xad, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xae, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xaf, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb0, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb1, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb2, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb3, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb4, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb5, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb6, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb7, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb8, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xb9, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xba, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xbb, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xbc, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xbd, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xbe, 0x0, 0x0, 0x0, - 0x2, 0xc3, 0xbf, 0x0, 0x0, 0x0 + (char)0x1, (char)0x0, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x8, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x9, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xa, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xb, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xc, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xd, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xe, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0xf, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x10, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x11, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x12, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x13, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x14, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x15, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x16, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x17, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x18, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x19, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x1f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x21, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x22, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x23, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x24, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x25, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x26, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x27, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x28, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x29, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x2f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x30, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x31, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x32, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x33, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x34, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x35, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x36, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x37, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x38, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x39, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x3f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x40, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x41, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x42, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x43, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x44, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x45, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x46, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x47, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x48, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x49, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x4f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x50, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x51, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x52, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x53, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x54, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x55, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x56, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x57, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x58, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x59, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x5f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x60, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x61, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x62, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x63, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x64, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x65, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x66, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x67, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x68, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x69, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x6f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x70, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x71, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x72, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x73, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x74, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x75, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x76, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x77, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x78, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x79, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7a, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7b, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7c, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7d, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7e, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x7f, (char)0x0, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x82, (char)0xac, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x3, (char)0xe2, (char)0x80, (char)0x9a, (char)0x0, (char)0x0, + (char)0x2, (char)0xc6, (char)0x92, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9e, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa6, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa1, (char)0x0, (char)0x0, + (char)0x2, (char)0xcb, (char)0x86, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xb0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xa0, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xb9, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x92, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x2, (char)0xc5, (char)0xbd, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x3, (char)0xe2, (char)0x80, (char)0x98, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x99, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9c, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x9d, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xa2, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x93, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0x94, (char)0x0, (char)0x0, + (char)0x2, (char)0xcb, (char)0x9c, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x84, (char)0xa2, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xa1, (char)0x0, (char)0x0, (char)0x0, + (char)0x3, (char)0xe2, (char)0x80, (char)0xba, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0x93, (char)0x0, (char)0x0, (char)0x0, + (char)0x1, (char)0x20, (char)0x0, (char)0x0, (char)0x0, (char)0x0, // not part of this charset + (char)0x2, (char)0xc5, (char)0xbe, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc5, (char)0xb8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa2, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa3, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xa9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xaa, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xab, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xac, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xad, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xae, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xaf, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb2, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb3, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xb9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xba, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xbb, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xbc, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xbd, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xbe, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc2, (char)0xbf, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x80, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x81, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x82, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x83, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x84, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x85, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x86, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x87, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x88, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x89, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8c, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8d, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x8f, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x90, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x91, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x92, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x93, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x94, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x95, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x96, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x97, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x98, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x99, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9a, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9b, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9c, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9d, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9e, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0x9f, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa2, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa3, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xa9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xaa, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xab, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xac, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xad, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xae, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xaf, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb0, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb1, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb2, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb3, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb4, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb5, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb6, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb7, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb8, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xb9, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xba, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xbb, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xbc, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xbd, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xbe, (char)0x0, (char)0x0, (char)0x0, + (char)0x2, (char)0xc3, (char)0xbf, (char)0x0, (char)0x0, (char)0x0 }; } diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index 203b406810..507f82c1a3 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -1,13 +1,13 @@ project(resources) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/caustic_0.png "${OpenMW_BINARY_DIR}/resources/water/caustic_0.png" COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Example_Fresnel.cg "${OpenMW_BINARY_DIR}/resources/water/Example_Fresnel.cg" COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Example_FresnelPS.asm "${OpenMW_BINARY_DIR}/resources/water/Example_FresnelPS.asm" COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/GlassFP.cg "${OpenMW_BINARY_DIR}/resources/water/GlassFP.cg" COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/GlassVP.cg "${OpenMW_BINARY_DIR}/resources/water/GlassVP.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/underwater.cg "${OpenMW_BINARY_DIR}/resources/water/underwater.cg" COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/perlinvolume.dds "${OpenMW_BINARY_DIR}/resources/water/perlinvolume.dds" COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Water02.jpg "${OpenMW_BINARY_DIR}/resources/water/Water02.jpg" COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.compositor "${OpenMW_BINARY_DIR}/resources/water/water.compositor" COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/waves2.dds "${OpenMW_BINARY_DIR}/resources/water/waves2.dds" COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Examples-Water.material "${OpenMW_BINARY_DIR}/resources/water/Examples-Water.material" COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/WaterNormal1.tga "${OpenMW_BINARY_DIR}/resources/water/WaterNormal1.tga" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.material "${OpenMW_BINARY_DIR}/resources/water/water.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/WaterNormal2.tga "${OpenMW_BINARY_DIR}/resources/water/WaterNormal2.tga" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.cg "${OpenMW_BINARY_DIR}/resources/water/water.cg" COPYONLY) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.cg "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.cg" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.material "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.compositor "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.compositor" COPYONLY) diff --git a/files/gbuffer/gbuffer.cg b/files/gbuffer/gbuffer.cg new file mode 100644 index 0000000000..c7f2fe6788 --- /dev/null +++ b/files/gbuffer/gbuffer.cg @@ -0,0 +1,18 @@ +void RenderScene_vs(in float4 position : POSITION + ,in float2 uv :TEXCOORD0 + ,uniform float4x4 wvp + ,out float4 oPosition : POSITION + ,out float2 oUV :TEXCOORD0) +{ + oPosition = mul(wvp, position); + oUV = uv; +} + +void RenderScene_ps(in float4 position : POSITION + ,in float2 uv :TEXCOORD0 + ,uniform sampler2D tex1 : TEXUNIT0 + ,out float4 oColor : COLOR) +{ + float4 scene =tex2D(tex1, uv); + oColor= scene; +} diff --git a/files/gbuffer/gbuffer.compositor b/files/gbuffer/gbuffer.compositor new file mode 100644 index 0000000000..316003af6b --- /dev/null +++ b/files/gbuffer/gbuffer.compositor @@ -0,0 +1,95 @@ +// Compositor that just controls output to the MRT textures +compositor gbuffer +{ + technique + { + // MRT output. Currently this is a color texture plus a depth texture + texture mrt_output target_width target_height PF_FLOAT16_RGBA PF_FLOAT16_RGBA chain_scope depth_pool 2 + + target mrt_output + { + input none + pass clear + { + clear + { + // make sure to set this to the viewport background color from outside + colour_value 0 0 0 1 + } + } + pass render_scene + { + // Renders everything except water + first_render_queue 0 + last_render_queue 70 + } + + } + + target_output + { + input none + + pass render_quad + { + material RenderScene + input 0 mrt_output 0 + } + } + } +} + +// Finalizer compositor to render objects that we don't want in the MRT textures (ex. water) +// NB the water has to be rendered in a seperate compositor anyway, because it +// accesses the MRT textures which can't be done while they are still being rendered to. +compositor gbufferFinalizer +{ + technique + { + texture no_mrt_output target_width target_height PF_R8G8B8A8 depth_pool 2 no_fsaa + texture previousscene target_width target_height PF_R8G8B8A8 + + target previousscene + { + input previous + } + target no_mrt_output + { + input none + shadows off + pass clear + { + clear + { + buffers colour + colour_value 0 0 0 0 + } + } + pass render_quad + { + material RenderSceneNoDepth + input 0 previousscene + } + pass render_scene + { + first_render_queue 71 + last_render_queue 100 + } + } + target_output + { + input none + pass clear + { + clear + { + } + } + pass render_quad + { + material RenderSceneNoDepth + input 0 no_mrt_output + } + } + } +} diff --git a/files/gbuffer/gbuffer.material b/files/gbuffer/gbuffer.material new file mode 100644 index 0000000000..faa8dd4980 --- /dev/null +++ b/files/gbuffer/gbuffer.material @@ -0,0 +1,63 @@ +vertex_program RenderGBuffer_vs cg +{ + source gbuffer.cg + profiles vs_4_0 vs_1_1 arbvp1 + entry_point RenderScene_vs + default_params + { + param_named_auto wvp worldviewproj_matrix + } +} +fragment_program RenderGBuffer_ps cg +{ + source gbuffer.cg + entry_point RenderScene_ps + profiles ps_4_0 ps_2_x arbfp1 + default_params + { + } +} +material RenderScene +{ + technique + { + pass + { + vertex_program_ref RenderGBuffer_vs + { + } + + fragment_program_ref RenderGBuffer_ps + { + } + + texture_unit tex1 + { + //scenebuffer + } + } + } +} + +material RenderSceneNoDepth +{ + technique + { + pass + { + depth_write off + vertex_program_ref RenderGBuffer_vs + { + } + + fragment_program_ref RenderGBuffer_ps + { + } + + texture_unit tex1 + { + //scenebuffer + } + } + } +} diff --git a/files/mygui/openmw_hud_layout.xml b/files/mygui/openmw_hud_layout.xml index 20370770ef..2dafa72988 100644 --- a/files/mygui/openmw_hud_layout.xml +++ b/files/mygui/openmw_hud_layout.xml @@ -11,22 +11,24 @@ align="Left Bottom" name="Stamina"/> - - + + + + + - - - + + + + + - - diff --git a/files/mygui/openmw_map_window_layout.xml b/files/mygui/openmw_map_window_layout.xml index f5c2c9991d..fbba8ddf47 100644 --- a/files/mygui/openmw_map_window_layout.xml +++ b/files/mygui/openmw_map_window_layout.xml @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/openmw_stats_window_layout.xml b/files/mygui/openmw_stats_window_layout.xml index 1380d474cd..fd99f863e5 100644 --- a/files/mygui/openmw_stats_window_layout.xml +++ b/files/mygui/openmw_stats_window_layout.xml @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/openmw_windows.skin.xml b/files/mygui/openmw_windows.skin.xml index 3ee33124ca..7c194ea5d0 100644 --- a/files/mygui/openmw_windows.skin.xml +++ b/files/mygui/openmw_windows.skin.xml @@ -289,6 +289,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/settings-default.cfg b/files/settings-default.cfg new file mode 100644 index 0000000000..4b86cba927 --- /dev/null +++ b/files/settings-default.cfg @@ -0,0 +1,84 @@ +[General] +# Camera field of view +field of view = 55 + +# Texture filtering mode. valid values: +# anisotropic +# bilinear +# trilinear +texture filtering = anisotropic + +# Has no effect when texture filtering is not anisotropic +anisotropy = 4 + +# Number of texture mipmaps to generate +num mipmaps = 5 + +[HUD] +# FPS counter +# 0: not visible +# 1: basic FPS display +# 2: advanced FPS display (batches, triangles) +fps = 0 + +[Objects] +shaders = true + +# Max. number of lights that affect objects. Setting to 1 will only reflect sunlight +# Note: has no effect when shaders are turned off +num lights = 8 + +# Use static geometry for static objects. Improves rendering speed. +use static geometry = true + +[Viewing distance] +# Limit the rendering distance of small objects +limit small object distance = false + +# Size below which an object is considered as small +small object size = 250 + +# Rendering distance for small objects +small object distance = 3500 + +# Max viewing distance at clear weather conditions +max viewing distance = 5600 + +# Distance at which fog starts (proportional to viewing distance) +fog start factor = 0.5 + +# Distance at which fog ends (proportional to viewing distance) +fog end factor = 1.0 + +[Terrain] +# Max. number of lights that affect the terrain. Setting to 1 will only reflect sunlight +num lights = 8 + +[Water] +# Enable this to get fancy-looking water with reflections and refractions +# All the settings below have no effect if this is false +shader = true + +rtt size = 512 + +reflect terrain = true + +reflect statics = false + +reflect small statics = false + +reflect actors = true + +reflect misc = false + +# Enable underwater effect. It is not resource intensive, so only disable it if you have problems. +underwater effect = true + +[Sound] +# Device name. Blank means default +device = + +# Volumes. Sfx and music volumes are both affected by the master volume +master volume = 1.0 +sfx volume = 1.0 +music volume = 0.4 diff --git a/files/water/Example_Fresnel.cg b/files/water/Example_Fresnel.cg deleted file mode 100644 index e091fc5878..0000000000 --- a/files/water/Example_Fresnel.cg +++ /dev/null @@ -1,116 +0,0 @@ -// Vertex program for fresnel reflections / refractions -void main_vp( - float4 pos : POSITION, - float4 normal : NORMAL, - float2 tex : TEXCOORD0, - - out float4 oPos : POSITION, - out float3 noiseCoord : TEXCOORD0, - out float4 projectionCoord : TEXCOORD1, - out float3 oEyeDir : TEXCOORD2, - out float3 oNormal : TEXCOORD3, - - uniform float4x4 worldViewProjMatrix, - uniform float3 eyePosition, // object space - uniform float timeVal, - uniform float scale, // the amount to scale the noise texture by - uniform float scroll, // the amount by which to scroll the noise - uniform float noise // the noise perturb as a factor of the time - ) -{ - oPos = mul(worldViewProjMatrix, pos); - // Projective texture coordinates, adjust for mapping - float4x4 scalemat = float4x4(0.5, 0, 0, 0.5, - 0,-0.5, 0, 0.5, - 0, 0, 0.5, 0.5, - 0, 0, 0, 1); - projectionCoord = mul(scalemat, oPos); - // Noise map coords - noiseCoord.xy = (tex + (timeVal * scroll)) * scale; - noiseCoord.z = noise * timeVal; - - oEyeDir = normalize(pos.xyz - eyePosition); - oNormal = normal.rgb; - -} - -// Fragment program for distorting a texture using a 3D noise texture -void main_fp( - float3 noiseCoord : TEXCOORD0, - float4 projectionCoord : TEXCOORD1, - float3 eyeDir : TEXCOORD2, - float3 normal : TEXCOORD3, - - out float4 col : COLOR, - - uniform float4 tintColour, - uniform float noiseScale, - uniform float fresnelBias, - uniform float fresnelScale, - uniform float fresnelPower, - uniform sampler2D waterTex : register(s0), - uniform sampler2D noiseMap : register(s1), - uniform sampler2D reflectMap : register(s2), - uniform sampler2D refractMap : register(s3) - ) -{ - // Do the tex projection manually so we can distort _after_ - float2 final = projectionCoord.xy / projectionCoord.w; - - // Noise - float3 noiseNormal = (tex2D(noiseMap, (noiseCoord.xy / 5)).rgb - 0.5).rbg * noiseScale; - final += noiseNormal.xz; - - // Fresnel - //normal = normalize(normal + noiseNormal.xz); - float fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower); - - // Reflection / refraction - float4 reflectionColour = tex2D(reflectMap, final); - float4 refractionColour = tex2D(refractMap, final) + tintColour; - - // Final colour - col = lerp(refractionColour, reflectionColour, fresnel) * tex2D(waterTex, noiseNormal) / 3 ; - - -} - - -// Old version to match ATI PS 1.3 implementation -void main_vp_old( - float4 pos : POSITION, - float4 normal : NORMAL, - float2 tex : TEXCOORD0, - - out float4 oPos : POSITION, - out float fresnel : COLOR, - out float3 noiseCoord : TEXCOORD0, - out float4 projectionCoord : TEXCOORD1, - - uniform float4x4 worldViewProjMatrix, - uniform float3 eyePosition, // object space - uniform float fresnelBias, - uniform float fresnelScale, - uniform float fresnelPower, - uniform float timeVal, - uniform float scale, // the amount to scale the noise texture by - uniform float scroll, // the amount by which to scroll the noise - uniform float noise // the noise perturb as a factor of the time - ) -{ - oPos = mul(worldViewProjMatrix, pos); - // Projective texture coordinates, adjust for mapping - float4x4 scalemat = float4x4(0.5, 0, 0, 0.5, - 0,-0.5, 0, 0.5, - 0, 0, 0.5, 0.5, - 0, 0, 0, 1); - projectionCoord = mul(scalemat, oPos); - // Noise map coords - noiseCoord.xy = (tex + (timeVal * scroll)) * scale; - noiseCoord.z = noise * timeVal; - - // calc fresnel factor (reflection coefficient) - float3 eyeDir = normalize(pos.xyz - eyePosition); - fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower); - -} diff --git a/files/water/Example_FresnelPS.asm b/files/water/Example_FresnelPS.asm deleted file mode 100644 index 2de078ef5a..0000000000 --- a/files/water/Example_FresnelPS.asm +++ /dev/null @@ -1,72 +0,0 @@ -ps.1.4 - // conversion from Cg generated ARB_fragment_program to ps.1.4 by NFZ - // command line args: -profile arbfp1 -entry main_fp - // program main_fp - // c0 : distortionRange - // c1 : tintColour - // testure 0 : noiseMap - // texture 1 : reflectMap - // texture 2 : refractMap - // v0.x : fresnel - // t0.xyz : noiseCoord - // t1.xyw : projectionCoord - -def c2, 2, 1, 0, 0 - - // Cg: distort.x = tex3D(noiseMap, noiseCoord).x; - // arbfp1: TEX R0.x, fragment.texcoord[0], texture[0], 3D; - // sample noise map using noiseCoord in TEX unit 0 - -texld r0, t0.xyz - - // get projected texture coordinates from TEX coord 1 - // will be used in phase 2 - -texcrd r1.xy, t1_dw.xyw -mov r1.z, c2.y - - // Cg: distort.y = tex3D(noiseMap, noiseCoord + yoffset).x; - // arbfp1: ADD R1.xyz, fragment.texcoord[0], c1; - // arbfp1: TEX R1.x, R1, texture[0], 3D; - // arbfp1: MOV R0.y, R1.x; - - // Cg: distort = (distort * 2 - 1) * distortionRange; - // arbfp1: MAD R0.xy, R0, c0.x, -c0.y; - // arbfp1: MUL R0.xy, R0, u0.x; - // (distort * 2 - 1) same as 2*(distort -.5) so use _bx2 - - - // Cg: final = projectionCoord.xy / projectionCoord.w; - // Cg: final += distort; - // arbfp1: RCP R0.w, fragment.texcoord[1].w; - // arbfp1: MAD R0.xy, fragment.texcoord[1], R0.w, R0; - // final = (distort * projectionCoord.w) + projectionCoord.xy - // for ps.1.4 have to re-arrange things a bit to perturb projected texture coordinates - -mad r0.xyz, r0_bx2, c0.x, r1 - -phase - - // do dependant texture reads - // Cg: reflectionColour = tex2D(reflectMap, final); - // arbfp1: TEX R0, R0, texture[1], 2D; - // sampe reflectMap using dependant read : texunit 1 - -texld r1, r0.xyz - - // Cg: refractionColour = tex2D(refractMap, final) + tintColour; - // arbfp1: TEX R1, R0, texture[2], 2D; - // sample refractMap : texunit 2 - -texld r2, r0.xyz - - // adding tintColour that is in global c1 - // arbfp1: ADD R1, R1, u1; - -add r2, r2, c1 - - // Cg: col = lerp(refractionColour, reflectionColour, fresnel); - // arbfp1: ADD R0, R0, -R1; - // arbfp1: MAD result.color, fragment.color.primary.x, R0, R1; - -lrp r0, v0.x, r1, r2 diff --git a/files/water/Examples-Water.material b/files/water/Examples-Water.material deleted file mode 100644 index 2b46d6e08d..0000000000 --- a/files/water/Examples-Water.material +++ /dev/null @@ -1,149 +0,0 @@ - -vertex_program Water/GlassVP cg -{ - source GlassVP.cg - entry_point glass_vp - profiles vs_1_1 arbvp1 - - default_params - { - param_named_auto worldViewProj worldviewproj_matrix - } -} - - -fragment_program Water/GlassFP cg -{ - source GlassFP.cg - entry_point main_ps - profiles ps_2_0 arbfp1 -} - -material Water/Compositor -{ - technique - { - pass - { - depth_check off - vertex_program_ref Water/GlassVP - { - param_named_auto timeVal time 0.25 - param_named scale float 0.1 - } - - fragment_program_ref Water/GlassFP - { - param_named tintColour float4 0 0.35 0.35 1 - } - - texture_unit RT - { - tex_coord_set 0 - tex_address_mode clamp - filtering linear linear linear - } - - texture_unit - { - texture WaterNormal1.tga 2d - tex_coord_set 1 - //tex_address_mode clamp - filtering linear linear linear - } - texture_unit - { - texture caustic_0.png 2d - tex_coord_set 2 - //tex_address_mode clamp - filtering linear linear linear - } - } - } -} -vertex_program Water/RefractReflectVP cg -{ - source Example_Fresnel.cg - entry_point main_vp - profiles vs_1_1 arbvp1 -} -vertex_program Water/RefractReflectVPold cg -{ - source Example_Fresnel.cg - entry_point main_vp_old - profiles vs_1_1 arbvp1 -} - -fragment_program Water/RefractReflectFP cg -{ - source Example_Fresnel.cg - entry_point main_fp - // sorry, ps_1_1 and fp20 can't do this - profiles ps_2_0 arbfp1 -} - -fragment_program Water/RefractReflectPS asm -{ - source Example_FresnelPS.asm - // sorry, only for ps_1_4 :) - syntax ps_1_4 - -} -material Examples/Water0 -{ - - technique - { - pass - { - // - - depth_write off - vertex_program_ref Water/RefractReflectVP - { - param_named_auto worldViewProjMatrix worldviewproj_matrix - param_named_auto eyePosition camera_position_object_space - param_named_auto timeVal time 0.15 - param_named scroll float 1 - param_named scale float 1 - param_named noise float 1 - // scroll and noisePos will need updating per frame - } - fragment_program_ref Water/RefractReflectFP - { - param_named fresnelBias float -0.1 - param_named fresnelScale float 0.8 - param_named fresnelPower float 20 - param_named tintColour float4 1 1 1 1 - param_named noiseScale float 0.05 - } - // Water - scene_blend alpha_blend - texture_unit - { - - // Water texture - texture Water02.jpg - // min / mag filtering, no mip - filtering linear linear none - alpha_op_ex source1 src_manual src_current 0.9 - - } - // Noise - texture_unit - { - alpha_op_ex source1 src_manual src_current 0.9 - // Perlin noise volume - texture waves2.dds - // min / mag filtering, no mip - filtering linear linear none - } - - - } - - - } - -} - diff --git a/files/water/GlassFP.cg b/files/water/GlassFP.cg deleted file mode 100644 index eb18885d25..0000000000 --- a/files/water/GlassFP.cg +++ /dev/null @@ -1,15 +0,0 @@ -sampler RT : register(s0); -sampler NormalMap : register(s1); -sampler CausticMap : register(s2); - -float4 main_ps(float2 iTexCoord : TEXCOORD0, - float3 noiseCoord : TEXCOORD1, - uniform float4 tintColour) : COLOR -{ - float4 normal = tex2D(NormalMap, noiseCoord); - - - return tex2D(RT, iTexCoord + normal.xy * 0.05) + - (tex2D(CausticMap, noiseCoord) / 5) + - tintColour ; -} diff --git a/files/water/GlassVP.cg b/files/water/GlassVP.cg deleted file mode 100644 index 71153769c2..0000000000 --- a/files/water/GlassVP.cg +++ /dev/null @@ -1,24 +0,0 @@ -void glass_vp -( - in float4 inPos : POSITION, - - out float4 pos : POSITION, - out float2 uv0 : TEXCOORD0, - out float4 noiseCoord : TEXCOORD1, - - uniform float4x4 worldViewProj, - uniform float timeVal, - uniform float scale -) -{ - // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc) - pos = mul(worldViewProj, inPos); - - // The input positions adjusted by texel offsets, so clean up inaccuracies - inPos.xy = sign(inPos.xy); - - // Convert to image-space - uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f; - noiseCoord = (pos + timeVal) * scale; -} - diff --git a/files/water/Water02.jpg b/files/water/Water02.jpg deleted file mode 100644 index 3efda7b6a8..0000000000 Binary files a/files/water/Water02.jpg and /dev/null differ diff --git a/files/water/WaterNormal1.tga b/files/water/WaterNormal1.tga deleted file mode 100644 index a9ca11b7ed..0000000000 Binary files a/files/water/WaterNormal1.tga and /dev/null differ diff --git a/files/water/WaterNormal2.tga b/files/water/WaterNormal2.tga new file mode 100644 index 0000000000..771d150419 Binary files /dev/null and b/files/water/WaterNormal2.tga differ diff --git a/files/water/underwater.cg b/files/water/underwater.cg new file mode 100644 index 0000000000..b853dd5355 --- /dev/null +++ b/files/water/underwater.cg @@ -0,0 +1,61 @@ +void main_vp +( + in float4 inPos : POSITION, + + out float4 pos : POSITION, + out float2 uv0 : TEXCOORD0, + out float4 noiseCoord : TEXCOORD1, + + uniform float4x4 worldViewProj, + uniform float timeVal, + uniform float scale +) +{ + // Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc) + pos = mul(worldViewProj, inPos); + + // The input positions adjusted by texel offsets, so clean up inaccuracies + inPos.xy = sign(inPos.xy); + + // Convert to image-space + uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f; + noiseCoord = (pos + timeVal) * scale; +} + + + +float4 main_fp_nomrt (float2 iTexCoord : TEXCOORD0, + float3 noiseCoord : TEXCOORD1, + uniform sampler2D RT : register(s0), + uniform sampler2D NormalMap : register(s1), + uniform sampler2D CausticMap : register(s2), + uniform float4 tintColour) : COLOR +{ + float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1; + + return tex2D(RT, iTexCoord + normal.xy * 0.015) + + (tex2D(CausticMap, noiseCoord) / 5) + + tintColour ; +} + + +float4 main_fp (float2 iTexCoord : TEXCOORD0, + float3 noiseCoord : TEXCOORD1, + uniform float far, + uniform sampler2D RT : register(s0), + uniform sampler2D NormalMap : register(s1), + uniform sampler2D CausticMap : register(s2), + uniform sampler2D DepthMap : register(s3), + uniform float4 tintColour) : COLOR +{ + float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1; + + float depth = tex2D(DepthMap, iTexCoord + normal.xy * 0.015).r * far; + depth = saturate(depth / 2000.f); + + float4 color = tex2D(RT, iTexCoord + normal.xy * 0.015) + + (tex2D(CausticMap, noiseCoord) / 5) + + tintColour; + + return lerp(color, float4(0, 0.65, 0.65, 1), depth); +} diff --git a/files/water/water.cg b/files/water/water.cg new file mode 100644 index 0000000000..bf6d04c5cc --- /dev/null +++ b/files/water/water.cg @@ -0,0 +1,121 @@ +void main_vp +( + in float4 iPos : POSITION + , in float2 iUv : TEXCOORD0 + + , out float4 oPos : POSITION + , out float3 oScreenCoords : TEXCOORD0 + , out float2 oUv : TEXCOORD1 + , out float oDepth : TEXCOORD2 + , out float4 oEyeVector : TEXCOORD3 + + , uniform float4x4 wvpMat + , uniform float4 camPosObjSpace +) +{ + oPos = mul(wvpMat, iPos); + + oUv = iUv * 10; // uv scale + oDepth = oPos.z; + + float4x4 scalemat = float4x4( 0.5, 0, 0, 0.5, + 0, -0.5, 0, 0.5, + 0, 0, 0.5, 0.5, + 0, 0, 0, 1 ); + float4 texcoordProj = mul(scalemat, oPos); + oScreenCoords = float3(texcoordProj.x, texcoordProj.y, texcoordProj.w); + + oEyeVector = camPosObjSpace - iPos; +} + +void main_fp +( + out float4 oColor : COLOR + + , in float3 iScreenCoords : TEXCOORD0 + , in float2 iUv : TEXCOORD1 + , in float iDepth : TEXCOORD2 + , in float4 iEyeVector : TEXCOORD3 + , uniform float renderTargetFlipping + , uniform float4 lightPosObjSpace0 + , uniform float4 lightSpecularColour0 + + , uniform sampler2D reflectionMap : register(s0) + , uniform sampler2D refractionMap : register(s1) + , uniform sampler2D depthMap : register(s2) + , uniform sampler2D normalMap : register(s3) + , uniform float time + , uniform float far + , uniform float4 fogParams + , uniform float4 fogColour + , uniform float isUnderwater +) +{ + + float2 screenCoords = iScreenCoords.xy / iScreenCoords.z; + screenCoords.y = (1-saturate(renderTargetFlipping))+renderTargetFlipping*screenCoords.y; + + // No need for transparency since we are using a refraction map + oColor.a = 1; + + // Sample screen-space depth map and subtract pixel depth to get the real water depth + float depthTex = tex2D(depthMap, screenCoords).r; + float depth1 = depthTex * far - iDepth; + depth1 = saturate(depth1 / 500.f); + + // Simple wave effect. to be replaced by something better + float2 uv1 = iUv + time * float2(0.5, 0); + float2 uv2 = iUv + time * float2(0, 0.5); + float2 uv3 = iUv + time * float2(-0.5, 0); + float2 uv4 = iUv + time * float2(0, -0.5); + float4 normal = tex2D(normalMap, uv1) + tex2D(normalMap, uv2) + tex2D(normalMap, uv3) + tex2D(normalMap, uv4); + normal = normal / 4.f; + normal = 2*normal - 1; + + float2 screenCoords_reflect = screenCoords + normal.yx * 0.05; + float2 screenCoords_refract = screenCoords + normal.yx * 0.05 * depth1; + + // Sample depth again with the refracted coordinates + depthTex = tex2D(depthMap, screenCoords_refract).r; + float depth2 = (depthTex * far - iDepth) / 500.f; + depth2 = (depthTex == 0 ? 1 : depth2); + // if depth2 is less than 0, this means we would refract something which is above water, + // which we don't want to - so in that case, don't refract + if (depth2 < 0.25) // delta due to inaccuracies + { + screenCoords_refract = screenCoords; + depth2 = depth1; + } + depth2 = saturate(depth2); + + float4 reflection = tex2D(reflectionMap, screenCoords_reflect); + float4 refraction = tex2D(refractionMap, screenCoords_refract); + + // tangent to object space + normal.xyz = normal.xzy; + + iEyeVector.xyz = normalize(iEyeVector.xyz); + + // fresnel + float facing = 1.0 - max(abs(dot(iEyeVector.xyz, normal.xyz)), 0); + float reflectionFactor = saturate(0.35 + 0.65 * pow(facing, 2)); + + // specular + float3 lightDir = normalize(lightPosObjSpace0.xyz); // assumes that light 0 is a directional light + float3 halfVector = normalize(iEyeVector + lightDir); + float specular = pow(max(dot(normal.xyz, halfVector.xyz), 0), 64); + + float opacity = depth2 * saturate(reflectionFactor + specular); + opacity *= (1-isUnderwater); + + reflection.xyz += lightSpecularColour0.xyz * specular; + + oColor.xyz = lerp(refraction.xyz, reflection.xyz, opacity); + + oColor.xyz += isUnderwater * float3(0, 0.35, 0.35); // underwater tint color + oColor.xyz = lerp(oColor.xyz, float3(0, 0.65, 0.65), saturate(isUnderwater * (iDepth / 2000.f))); // underwater fog + + // add fog + //float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); + //oColor.xyz = lerp(oColor.xyz, fogColour, fogValue); +} diff --git a/files/water/water.compositor b/files/water/water.compositor index 67bf908960..8d9c3cb396 100644 --- a/files/water/water.compositor +++ b/files/water/water.compositor @@ -1,4 +1,4 @@ -compositor Water +compositor UnderwaterNoMRT { technique { @@ -13,9 +13,34 @@ compositor Water pass render_quad { - material Water/Compositor + material Water/CompositorNoMRT input 0 rt0 } } } -} +} + + +compositor Underwater +{ + technique + { + texture_ref scene gbuffer mrt_output + texture rt0 target_width target_height PF_R8G8B8 + + target rt0 { input previous } + + target_output + { + // Start with clear output + input none + + pass render_quad + { + material Water/Compositor + input 0 rt0 + input 3 scene 1 + } + } + } +} diff --git a/files/water/water.material b/files/water/water.material new file mode 100644 index 0000000000..7ce6e7ba29 --- /dev/null +++ b/files/water/water.material @@ -0,0 +1,198 @@ +vertex_program UnderwaterEffectVP cg +{ + source underwater.cg + entry_point main_vp + profiles vs_1_1 arbvp1 + + default_params + { + param_named_auto worldViewProj worldviewproj_matrix + } +} + + +fragment_program UnderwaterEffectFP_NoMRT cg +{ + source underwater.cg + entry_point main_fp_nomrt + profiles ps_2_0 arbfp1 +} + +fragment_program UnderwaterEffectFP cg +{ + source underwater.cg + entry_point main_fp + profiles ps_2_0 arbfp1 +} + +vertex_program Water_VP cg +{ + source water.cg + entry_point main_vp + profiles vs_2_x arbvp1 + + default_params + { + param_named_auto wvpMat worldviewproj_matrix + } +} + +fragment_program Water_FP cg +{ + source water.cg + entry_point main_fp + profiles ps_2_x arbfp1 +} + +material Water +{ + technique + { + pass + { + cull_hardware none + + vertex_program_ref Water_VP + { + param_named_auto camPosObjSpace camera_position_object_space + } + fragment_program_ref Water_FP + { + param_named_auto time time 0.1 + //param_named_auto fogColour fog_colour + //param_named_auto fogParams fog_params + param_named_auto renderTargetFlipping render_target_flipping + param_named_auto far far_clip_distance + param_named_auto lightPosObjSpace0 light_position_object_space 0 + param_named_auto lightSpecularColour0 light_specular_colour 0 + param_named isUnderwater float 0 + } + + texture_unit reflectionMap + { + texture WaterReflection + tex_address_mode clamp + } + + texture_unit refractionMap + { + tex_address_mode clamp + } + + texture_unit depthMap + { + tex_address_mode clamp + } + + texture_unit normalMap + { + texture WaterNormal2.tga + } + } + } + technique + { + scheme Map + pass + { + cull_hardware none + scene_blend alpha_blend + depth_write off + diffuse 0 0 0 1 + emissive 0.6 0.7 1.0 + ambient 0 0 0 + texture_unit + { + // texture names set via code + scale 0.1 0.1 + alpha_op_ex source1 src_manual src_current 0.7 + } + } + } +} + +material Water/CompositorNoMRT +{ + technique + { + pass + { + depth_check off + vertex_program_ref UnderwaterEffectVP + { + param_named_auto timeVal time 0.25 + param_named scale float 0.1 + } + + fragment_program_ref UnderwaterEffectFP_NoMRT + { + param_named tintColour float4 0 0.35 0.35 1 + } + + texture_unit RT + { + tex_coord_set 0 + tex_address_mode clamp + filtering linear linear linear + } + + texture_unit + { + texture WaterNormal2.tga 2d + tex_coord_set 1 + //tex_address_mode clamp + filtering linear linear linear + } + texture_unit + { + texture caustic_0.png 2d + tex_coord_set 2 + //tex_address_mode clamp + filtering linear linear linear + } + } + } +} + +material Water/Compositor +{ + technique + { + pass + { + depth_check off + vertex_program_ref UnderwaterEffectVP + { + param_named_auto timeVal time 0.25 + param_named scale float 0.1 + } + + fragment_program_ref UnderwaterEffectFP + { + param_named tintColour float4 0 0.35 0.35 1 + param_named_auto far far_clip_distance + } + + texture_unit RT + { + tex_coord_set 0 + tex_address_mode clamp + } + + texture_unit + { + texture WaterNormal2.tga 2d + tex_coord_set 2 + } + texture_unit + { + texture caustic_0.png 2d + tex_coord_set 3 + } + + texture_unit DepthMap + { + } + } + } +} diff --git a/files/water/waves2.dds b/files/water/waves2.dds deleted file mode 100644 index c379886fae..0000000000 Binary files a/files/water/waves2.dds and /dev/null differ diff --git a/libs/openengine/gui/layout.hpp b/libs/openengine/gui/layout.hpp index e73b2d1cea..05a23e8aea 100644 --- a/libs/openengine/gui/layout.hpp +++ b/libs/openengine/gui/layout.hpp @@ -103,7 +103,7 @@ namespace GUI )); } - void setVisible(bool b) + virtual void setVisible(bool b) { mMainWidget->setVisible(b); }