From 884d3ea4d8662b7ba3a17f75906d217d457aba08 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Tue, 8 Jan 2013 06:19:05 -0400 Subject: [PATCH 001/213] Rip out OIS, fill the holes with SDL goodness. WIP. --- CMakeLists.txt | 8 +- apps/openmw/CMakeLists.txt | 3 +- apps/openmw/mwinput/inputmanagerimp.cpp | 153 ++++++----- apps/openmw/mwinput/inputmanagerimp.hpp | 36 ++- apps/openmw/mwinput/sdlinputwrapper.cpp | 70 +++++ apps/openmw/mwinput/sdlinputwrapper.hpp | 35 +++ cmake/FindSDL2.cmake | 180 +++++++++++++ extern/oics/CMakeLists.txt | 1 + extern/oics/ICSInputControlSystem.cpp | 245 +++++++++--------- extern/oics/ICSInputControlSystem.h | 56 ++-- .../oics/ICSInputControlSystem_joystick.cpp | 113 ++++---- .../oics/ICSInputControlSystem_keyboard.cpp | 26 +- extern/oics/ICSInputControlSystem_mouse.cpp | 32 +-- extern/oics/ICSPrerequisites.h | 14 +- extern/oics/OISCompat.h | 90 +++++++ 15 files changed, 724 insertions(+), 338 deletions(-) create mode 100644 apps/openmw/mwinput/sdlinputwrapper.cpp create mode 100644 apps/openmw/mwinput/sdlinputwrapper.hpp create mode 100644 cmake/FindSDL2.cmake create mode 100644 extern/oics/OISCompat.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 766167672..b1eb91d76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,7 +204,7 @@ endif() find_package(OGRE REQUIRED) find_package(MyGUI REQUIRED) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) -find_package(OIS REQUIRED) +find_package(SDL2 REQUIRED) find_package(OpenAL REQUIRED) find_package(Bullet REQUIRED) IF(OGRE_STATIC) @@ -218,7 +218,8 @@ ENDIF(OGRE_STATIC) include_directories("." ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_PLUGIN_INCLUDE_DIRS} ${OGRE_Terrain_INCLUDE_DIR} - ${OIS_INCLUDE_DIRS} ${Boost_INCLUDE_DIR} + ${SDL2_INCLUDE_DIR} + ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} ${MYGUI_INCLUDE_DIRS} ${MYGUI_PLATFORM_INCLUDE_DIRS} @@ -227,7 +228,7 @@ include_directories("." ${LIBDIR} ) -link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR}) +link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR}) if (APPLE) # List used Ogre plugins @@ -361,6 +362,7 @@ if(DPKG_PROGRAM) SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") + #TODO: should SDL2 be mentioned in here somewhere? SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 56147b500..88a05c810 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -20,7 +20,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - inputmanagerimp + inputmanagerimp sdlinputwrapper ) add_openmw_dir (mwgui @@ -103,6 +103,7 @@ target_link_libraries(openmw ${SOUND_INPUT_LIBRARY} ${BULLET_LIBRARIES} ${MYGUI_LIBRARIES} + ${SDL2_LIBRARY} ${MYGUI_PLATFORM_LIBRARIES} "shiny" "shiny.OgrePlatform" diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 995da8f34..a6f0f64d4 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -9,8 +9,6 @@ #include -#include - #include #include #include @@ -25,6 +23,8 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" +using namespace ICS; + namespace MWInput { InputManager::InputManager(OEngine::Render::OgreRenderer &ogre, @@ -59,14 +59,19 @@ namespace MWInput window->getCustomAttribute("WINDOW", &windowHnd); + + // Set non-exclusive mouse and keyboard input if the user requested + // it. + + //TODO: re-enable this and make it work with SDL + /* + std::ostringstream windowHndStr; OIS::ParamList pl; windowHndStr << windowHnd; pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); - // Set non-exclusive mouse and keyboard input if the user requested - // it. if (debug) { #if defined OIS_WIN32_PLATFORM @@ -89,6 +94,7 @@ namespace MWInput std::string("true"))); #endif } + */ #if defined(__APPLE__) && !defined(__LP64__) // Give the application window focus to receive input events @@ -97,23 +103,16 @@ namespace MWInput SetFrontProcess(&psn); #endif - mInputManager = OIS::InputManager::createInputSystem( pl ); + mInputManager = new MWSDLInputWrapper(window); + mInputManager->setMouseEventCallback (this); + mInputManager->setKeyboardEventCallback (this); - // Create all devices - mKeyboard = static_cast(mInputManager->createInputObject - ( OIS::OISKeyboard, true )); - mMouse = static_cast(mInputManager->createInputObject - ( OIS::OISMouse, true )); - - mKeyboard->setEventCallback (this); - mMouse->setEventCallback (this); + std::string file = userFileExists ? userFile : ""; + mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); adjustMouseRegion (window->getWidth(), window->getHeight()); - MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs); - - std::string file = userFileExists ? userFile : ""; - mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); + MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, 0); loadKeyDefaults(); @@ -139,9 +138,7 @@ namespace MWInput delete mInputCtrl; - mInputManager->destroyInputObject(mKeyboard); - mInputManager->destroyInputObject(mMouse); - OIS::InputManager::destroyInputSystem(mInputManager); + delete mInputManager; } void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) @@ -240,8 +237,7 @@ namespace MWInput void InputManager::update(float dt, bool loading) { // Tell OIS to handle all input events - mKeyboard->capture(); - mMouse->capture(); + mInputManager->capture(); // inject some fake mouse movement to force updating MyGUI's widget states // this shouldn't do any harm since we're moving back to the original position afterwards @@ -304,7 +300,7 @@ namespace MWInput if (mControlSwitch["playerviewswitch"]) { // work around preview mode toggle when pressing Alt+Tab - if (actionIsActive(A_TogglePOV) && !mKeyboard->isModifierDown (OIS::Keyboard::Alt)) { + if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(KMOD_ALT)) { if (mPreviewPOVDelay <= 0.5 && (mPreviewPOVDelay += dt) > 0.5) { @@ -419,37 +415,38 @@ namespace MWInput void InputManager::adjustMouseRegion(int width, int height) { - const OIS::MouseState &ms = mMouse->getMouseState(); - ms.width = width; - ms.height = height; + mInputCtrl->adjustMouseRegion(width, height); } - bool InputManager::keyPressed( const OIS::KeyEvent &arg ) + bool InputManager::keyPressed( const SDL_KeyboardEvent &arg ) { mInputCtrl->keyPressed (arg); - unsigned int text = arg.text; + unsigned int text = arg.keysym.unicode; + + //TODO: Check if we need this with SDL + /* #ifdef __APPLE__ // filter \016 symbol for F-keys on OS X - if ((arg.key >= OIS::KC_F1 && arg.key <= OIS::KC_F10) || - (arg.key >= OIS::KC_F11 && arg.key <= OIS::KC_F15)) { + if ((arg.key >= SDLK_F1 && arg.key <= SDLK_F10) || + (arg.key >= SDLK_F11 && arg.key <= SDLK_F15)) { text = 0; } #endif - - MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.key), text); + */ + MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.keysym.sym), text); return true; } - bool InputManager::keyReleased( const OIS::KeyEvent &arg ) + bool InputManager::keyReleased(const SDL_KeyboardEvent &arg ) { mInputCtrl->keyReleased (arg); - MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.key)); + MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.keysym.sym)); return true; } - bool InputManager::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) + bool InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) { mInputCtrl->mousePressed (arg, id); @@ -467,7 +464,7 @@ namespace MWInput return true; } - bool InputManager::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) + bool InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) { mInputCtrl->mouseReleased (arg, id); @@ -476,7 +473,7 @@ namespace MWInput return true; } - bool InputManager::mouseMoved( const OIS::MouseEvent &arg ) + bool InputManager::mouseMoved( const ICS::MWSDLMouseMotionEvent &arg ) { mInputCtrl->mouseMoved (arg); @@ -488,11 +485,13 @@ namespace MWInput // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor - mMouseX += float(arg.state.X.rel) * mUISensitivity; - mMouseY += float(arg.state.Y.rel) * mUISensitivity * mUIYMultiplier; + mMouseX += float(arg.xrel) * mUISensitivity; + mMouseY += float(arg.yrel) * mUISensitivity * mUIYMultiplier; mMouseX = std::max(0.f, std::min(mMouseX, float(viewSize.width))); mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height))); - mMouseWheel = arg.state.Z.abs; + + //there's no such thing as an absolute z position, so let's keep track of it ourselves + mMouseWheel += arg.zrel; MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel); } @@ -501,8 +500,8 @@ namespace MWInput { resetIdleTime(); - float x = arg.state.X.rel * mCameraSensitivity * 0.2; - float y = arg.state.Y.rel * mCameraSensitivity * 0.2 * (mInvertY ? -1 : 1) * mUIYMultiplier; + float x = arg.xrel * mCameraSensitivity * 0.2; + float y = arg.yrel * mCameraSensitivity * 0.2 * (mInvertY ? -1 : 1) * mUIYMultiplier; MWBase::World *world = MWBase::Environment::get().getWorld(); world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); @@ -679,38 +678,38 @@ namespace MWInput // across different versions of OpenMW (in the case where another input action is added) std::map defaultKeyBindings; - defaultKeyBindings[A_Activate] = OIS::KC_SPACE; - defaultKeyBindings[A_MoveBackward] = OIS::KC_S; - defaultKeyBindings[A_MoveForward] = OIS::KC_W; - defaultKeyBindings[A_MoveLeft] = OIS::KC_A; - defaultKeyBindings[A_MoveRight] = OIS::KC_D; - defaultKeyBindings[A_ToggleWeapon] = OIS::KC_F; - defaultKeyBindings[A_ToggleSpell] = OIS::KC_R; - defaultKeyBindings[A_QuickKeysMenu] = OIS::KC_F1; - defaultKeyBindings[A_Console] = OIS::KC_F2; - defaultKeyBindings[A_Crouch] = OIS::KC_LCONTROL; - defaultKeyBindings[A_AutoMove] = OIS::KC_Q; - defaultKeyBindings[A_Jump] = OIS::KC_E; - defaultKeyBindings[A_Journal] = OIS::KC_J; - defaultKeyBindings[A_Rest] = OIS::KC_T; - defaultKeyBindings[A_GameMenu] = OIS::KC_ESCAPE; - defaultKeyBindings[A_TogglePOV] = OIS::KC_TAB; - defaultKeyBindings[A_QuickKey1] = OIS::KC_1; - defaultKeyBindings[A_QuickKey2] = OIS::KC_2; - defaultKeyBindings[A_QuickKey3] = OIS::KC_3; - defaultKeyBindings[A_QuickKey4] = OIS::KC_4; - defaultKeyBindings[A_QuickKey5] = OIS::KC_5; - defaultKeyBindings[A_QuickKey6] = OIS::KC_6; - defaultKeyBindings[A_QuickKey7] = OIS::KC_7; - defaultKeyBindings[A_QuickKey8] = OIS::KC_8; - defaultKeyBindings[A_QuickKey9] = OIS::KC_9; - defaultKeyBindings[A_QuickKey10] = OIS::KC_0; - defaultKeyBindings[A_Screenshot] = OIS::KC_SYSRQ; - defaultKeyBindings[A_ToggleHUD] = OIS::KC_F12; + defaultKeyBindings[A_Activate] = SDLK_SPACE; + defaultKeyBindings[A_MoveBackward] = SDLK_s; + defaultKeyBindings[A_MoveForward] = SDLK_w; + defaultKeyBindings[A_MoveLeft] = SDLK_a; + defaultKeyBindings[A_MoveRight] = SDLK_d; + defaultKeyBindings[A_ToggleWeapon] = SDLK_f; + defaultKeyBindings[A_ToggleSpell] = SDLK_r; + defaultKeyBindings[A_QuickKeysMenu] = SDLK_F1; + defaultKeyBindings[A_Console] = SDLK_F2; + defaultKeyBindings[A_Crouch] = SDLK_LCTRL; + defaultKeyBindings[A_AutoMove] = SDLK_q; + defaultKeyBindings[A_Jump] = SDLK_e; + defaultKeyBindings[A_Journal] = SDLK_j; + defaultKeyBindings[A_Rest] = SDLK_t; + defaultKeyBindings[A_GameMenu] = SDLK_ESCAPE; + defaultKeyBindings[A_TogglePOV] = SDLK_TAB; + defaultKeyBindings[A_QuickKey1] = SDLK_1; + defaultKeyBindings[A_QuickKey2] = SDLK_2; + defaultKeyBindings[A_QuickKey3] = SDLK_3; + defaultKeyBindings[A_QuickKey4] = SDLK_4; + defaultKeyBindings[A_QuickKey5] = SDLK_5; + defaultKeyBindings[A_QuickKey6] = SDLK_6; + defaultKeyBindings[A_QuickKey7] = SDLK_7; + defaultKeyBindings[A_QuickKey8] = SDLK_8; + defaultKeyBindings[A_QuickKey9] = SDLK_9; + defaultKeyBindings[A_QuickKey10] = SDLK_0; + defaultKeyBindings[A_Screenshot] = SDLK_SYSREQ; + defaultKeyBindings[A_ToggleHUD] = SDLK_F12; std::map defaultMouseButtonBindings; - defaultMouseButtonBindings[A_Inventory] = OIS::MB_Right; - defaultMouseButtonBindings[A_Use] = OIS::MB_Left; + defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT; + defaultMouseButtonBindings[A_Use] = SDL_BUTTON_LEFT; for (int i = 0; i < A_Last; ++i) { @@ -728,14 +727,14 @@ namespace MWInput } if (!controlExists || force || - ( mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) == OIS::KC_UNASSIGNED + ( mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) == SDLK_UNKNOWN && mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) { clearAllBindings (control); if (defaultKeyBindings.find(i) != defaultKeyBindings.end()) - mInputCtrl->addKeyBinding(control, static_cast(defaultKeyBindings[i]), ICS::Control::INCREASE); + mInputCtrl->addKeyBinding(control, static_cast(defaultKeyBindings[i]), ICS::Control::INCREASE); else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end()) mInputCtrl->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); } @@ -786,7 +785,7 @@ namespace MWInput ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control; - if (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE) != OIS::KC_UNASSIGNED) + if (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE) != SDLK_UNKNOWN) return mInputCtrl->keyCodeToString (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE)); else if (mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) return "#{sMouse} " + boost::lexical_cast(mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE)); @@ -842,7 +841,7 @@ namespace MWInput } void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction) + , SDL_Keycode key, ICS::Control::ControlChangingDirection direction) { clearAllBindings(control); ICS::DetectingBindingListener::keyBindingDetected (ICS, control, key, direction); @@ -892,7 +891,7 @@ namespace MWInput void InputManager::clearAllBindings (ICS::Control* control) { // right now we don't really need multiple bindings for the same action, so remove all others first - if (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) != OIS::KC_UNASSIGNED) + if (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) != SDLK_UNKNOWN) mInputCtrl->removeKeyBinding (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE)); if (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) mInputCtrl->removeMouseButtonBinding (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE)); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 9deed1f28..3677f9070 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -6,6 +6,7 @@ #include #include "../mwbase/inputmanager.hpp" +#include "sdlinputwrapper.hpp" namespace OEngine { @@ -35,18 +36,9 @@ namespace ICS class InputControlSystem; } -namespace OIS -{ - class Keyboard; - class Mouse; - class InputManager; -} - -#include -#include - #include #include +#include namespace MWInput { @@ -54,7 +46,12 @@ namespace MWInput /** * @brief Class that handles all input and key bindings for OpenMW. */ - class InputManager : public MWBase::InputManager, public OIS::KeyListener, public OIS::MouseListener, public ICS::ChannelListener, public ICS::DetectingBindingListener + class InputManager : + public MWBase::InputManager, + public ICS::MWSDLKeyListener, + public ICS::MWSDLMouseListener, + public ICS::ChannelListener, + public ICS::DetectingBindingListener { public: InputManager(OEngine::Render::OgreRenderer &_ogre, @@ -85,12 +82,12 @@ namespace MWInput virtual void resetToDefaultBindings(); public: - virtual bool keyPressed( const OIS::KeyEvent &arg ); - virtual bool keyReleased( const OIS::KeyEvent &arg ); + virtual bool keyPressed(const SDL_KeyboardEvent &arg ); + virtual bool keyReleased( const SDL_KeyboardEvent &arg ); - virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ); - virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ); - virtual bool mouseMoved( const OIS::MouseEvent &arg ); + virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ); + virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ); + virtual bool mouseMoved( const ICS::MWSDLMouseMotionEvent &arg ); virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue); @@ -98,7 +95,7 @@ namespace MWInput , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction); virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction); + , SDL_Keycode key, ICS::Control::ControlChangingDirection direction); virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control , unsigned int button, ICS::Control::ControlChangingDirection direction); @@ -125,9 +122,8 @@ namespace MWInput ICS::InputControlSystem* mInputCtrl; - OIS::Keyboard* mKeyboard; - OIS::Mouse* mMouse; - OIS::InputManager* mInputManager; + + MWSDLInputWrapper* mInputManager; std::string mUserFile; diff --git a/apps/openmw/mwinput/sdlinputwrapper.cpp b/apps/openmw/mwinput/sdlinputwrapper.cpp new file mode 100644 index 000000000..60c7e8f7a --- /dev/null +++ b/apps/openmw/mwinput/sdlinputwrapper.cpp @@ -0,0 +1,70 @@ +#include "sdlinputwrapper.hpp" +#include + +namespace MWInput +{ + MWSDLInputWrapper::MWSDLInputWrapper(Ogre::RenderWindow *window) : + mWindow(window), mStarted(false), mSDLWindow(NULL) + { + _start(); + } + + MWSDLInputWrapper::~MWSDLInputWrapper() + { + SDL_DestroyWindow(mSDLWindow); + mSDLWindow = NULL; + SDL_Quit(); + } + + void MWSDLInputWrapper::capture() + { + _start(); + + SDL_Event evt; + while(SDL_PollEvent(&evt)) + { + switch(evt.type) + { + case SDL_MOUSEMOTION: + mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.motion)); + break; + case SDL_MOUSEWHEEL: + mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.wheel)); + break; + case SDL_MOUSEBUTTONDOWN: + mMouseListener->mousePressed(evt.button, evt.button.button); + break; + case SDL_MOUSEBUTTONUP: + mMouseListener->mouseReleased(evt.button, evt.button.button); + break; + + case SDL_KEYDOWN: + mKeyboardListener->keyPressed(evt.key); + break; + case SDL_KEYUP: + mKeyboardListener->keyReleased(evt.key); + break; + } + } + } + + bool MWSDLInputWrapper::isModifierHeld(int mod) + { + return SDL_GetModState() & mod; + } + + void MWSDLInputWrapper::_start() + { + Uint32 flags = SDL_INIT_VIDEO; + if(SDL_WasInit(flags) == 0) + { + //get the HWND from ogre's renderwindow + size_t windowHnd; + mWindow->getCustomAttribute("WINDOW", &windowHnd); + + //just use that one for input + SDL_Init(flags); + mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); + } + } +} diff --git a/apps/openmw/mwinput/sdlinputwrapper.hpp b/apps/openmw/mwinput/sdlinputwrapper.hpp new file mode 100644 index 000000000..ee07efbdb --- /dev/null +++ b/apps/openmw/mwinput/sdlinputwrapper.hpp @@ -0,0 +1,35 @@ +#ifndef _MWINPUT_SDLINPUTWRAPPER_H +#define _MWINPUT_SDLINPUTWRAPPER_H + +#include "SDL2/SDL_events.h" +#include +#include + + +namespace MWInput +{ + class MWSDLInputWrapper + { + public: + MWSDLInputWrapper(Ogre::RenderWindow* window); + ~MWSDLInputWrapper(); + + void setMouseEventCallback(ICS::MWSDLMouseListener* listen) { mMouseListener = listen; } + void setKeyboardEventCallback(ICS::MWSDLKeyListener* listen) { mKeyboardListener = listen; } + + void capture(); + bool isModifierHeld(int mod); + + private: + ICS::MWSDLMouseListener* mMouseListener; + ICS::MWSDLKeyListener* mKeyboardListener; + Ogre::RenderWindow* mWindow; + SDL_Window* mSDLWindow; + + bool mStarted; + void _start(); + + }; +} + +#endif diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake new file mode 100644 index 000000000..614426ccc --- /dev/null +++ b/cmake/FindSDL2.cmake @@ -0,0 +1,180 @@ +# Locate SDL2 library +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2_main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDL2main.h and SDL2main.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL2 guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL2 convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). +# +# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake +# module with the minor edit of changing "SDL" to "SDL2" where necessary. This +# was not created for redistribution, and exists temporarily pending official +# SDL2 CMake modules. + +#============================================================================= +# Copyright 2003-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/include/SDL2 + /usr/include/SDL2 + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) +#MESSAGE("SDL2_INCLUDE_DIR is ${SDL2_INCLUDE_DIR}") + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt +) + +#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}") + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +SET(SDL2_FOUND "NO") +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") + + SET(SDL2_FOUND "YES") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 + REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/extern/oics/CMakeLists.txt b/extern/oics/CMakeLists.txt index 7c14387a4..2e2a7a6d6 100644 --- a/extern/oics/CMakeLists.txt +++ b/extern/oics/CMakeLists.txt @@ -9,6 +9,7 @@ set(OICS_SOURCE_FILES ICSInputControlSystem_keyboard.cpp ICSInputControlSystem_mouse.cpp ICSInputControlSystem_joystick.cpp + OISCompat.h tinyxml.cpp tinyxmlparser.cpp tinyxmlerror.cpp diff --git a/extern/oics/ICSInputControlSystem.cpp b/extern/oics/ICSInputControlSystem.cpp index 1702c853e..159b3241f 100644 --- a/extern/oics/ICSInputControlSystem.cpp +++ b/extern/oics/ICSInputControlSystem.cpp @@ -41,7 +41,7 @@ namespace ICS this->mActive = active; - this->fillOISKeysMap(); + this->fillSDLKeysMap(); ICS_LOG("Channel count = " + ToString(channelCount) ); for(size_t i=0;i::iterator it = mKeys.begin() + mKeys["UNASSIGNED"]= SDLK_UNKNOWN; + mKeys["ESCAPE"]= SDLK_ESCAPE; + mKeys["1"]= SDLK_1; + mKeys["2"]= SDLK_2; + mKeys["3"]= SDLK_3; + mKeys["4"]= SDLK_4; + mKeys["5"]= SDLK_5; + mKeys["6"]= SDLK_6; + mKeys["7"]= SDLK_7; + mKeys["8"]= SDLK_8; + mKeys["9"]= SDLK_9; + mKeys["0"]= SDLK_0; + mKeys["MINUS"]= SDLK_MINUS; + mKeys["EQUALS"]= SDLK_EQUALS; + mKeys["BACK"]= SDLK_BACKSPACE; + mKeys["TAB"]= SDLK_TAB; + mKeys["Q"]= SDLK_q; + mKeys["W"]= SDLK_w; + mKeys["E"]= SDLK_e; + mKeys["R"]= SDLK_r; + mKeys["T"]= SDLK_t; + mKeys["Y"]= SDLK_y; + mKeys["U"]= SDLK_u; + mKeys["I"]= SDLK_i; + mKeys["O"]= SDLK_o; + mKeys["P"]= SDLK_p; + mKeys["LBRACKET"]= SDLK_LEFTBRACKET; + mKeys["RBRACKET"]= SDLK_RIGHTBRACKET; + mKeys["RETURN"]= SDLK_RETURN; + mKeys["LCONTROL"]= SDLK_LCTRL; + mKeys["A"]= SDLK_a; + mKeys["S"]= SDLK_s; + mKeys["D"]= SDLK_d; + mKeys["F"]= SDLK_f; + mKeys["G"]= SDLK_g; + mKeys["H"]= SDLK_h; + mKeys["J"]= SDLK_j; + mKeys["K"]= SDLK_k; + mKeys["L"]= SDLK_l; + mKeys["SEMICOLON"]= SDLK_SEMICOLON; + mKeys["APOSTROPHE"]= SDLK_QUOTE; + mKeys["GRAVE"]= SDLK_BACKQUOTE; + mKeys["LSHIFT"]= SDLK_LSHIFT; + mKeys["BACKSLASH"]= SDLK_BACKSLASH; + mKeys["Z"]= SDLK_z; + mKeys["X"]= SDLK_x; + mKeys["C"]= SDLK_c; + mKeys["V"]= SDLK_v; + mKeys["B"]= SDLK_b; + mKeys["N"]= SDLK_n; + mKeys["M"]= SDLK_m; + mKeys["COMMA"]= SDLK_COMMA; + mKeys["PERIOD"]= SDLK_PERIOD; + mKeys["SLASH"]= SDLK_SLASH; + mKeys["RSHIFT"]= SDLK_RSHIFT; + mKeys["MULTIPLY"]= SDLK_ASTERISK; + mKeys["LMENU"]= SDLK_LALT; + mKeys["SPACE"]= SDLK_SPACE; + mKeys["CAPITAL"]= SDLK_CAPSLOCK; + mKeys["F1"]= SDLK_F1; + mKeys["F2"]= SDLK_F2; + mKeys["F3"]= SDLK_F3; + mKeys["F4"]= SDLK_F4; + mKeys["F5"]= SDLK_F5; + mKeys["F6"]= SDLK_F6; + mKeys["F7"]= SDLK_F7; + mKeys["F8"]= SDLK_F8; + mKeys["F9"]= SDLK_F9; + mKeys["F10"]= SDLK_F10; + mKeys["F11"]= SDLK_F11; + mKeys["F12"]= SDLK_F12; + mKeys["NUMLOCK"]= SDLK_NUMLOCKCLEAR; + mKeys["SCROLL"]= SDLK_SCROLLLOCK; + mKeys["NUMPAD7"]= SDLK_KP_7; + mKeys["NUMPAD8"]= SDLK_KP_8; + mKeys["NUMPAD9"]= SDLK_KP_9; + mKeys["SUBTRACT"]= SDLK_KP_MINUS; + mKeys["NUMPAD4"]= SDLK_KP_4; + mKeys["NUMPAD5"]= SDLK_KP_5; + mKeys["NUMPAD6"]= SDLK_KP_6; + mKeys["ADD"]= SDLK_KP_PLUS; + mKeys["NUMPAD1"]= SDLK_KP_1; + mKeys["NUMPAD2"]= SDLK_KP_2; + mKeys["NUMPAD3"]= SDLK_KP_3; + mKeys["NUMPAD0"]= SDLK_KP_0; + mKeys["DECIMAL"]= SDLK_KP_DECIMAL; + mKeys["RCONTROL"]= SDLK_RCTRL; + mKeys["DIVIDE"]= SDLK_SLASH; + mKeys["SYSRQ"]= SDLK_SYSREQ; + mKeys["RMENU"]= SDLK_RALT; + mKeys["PAUSE"]= SDLK_PAUSE; + mKeys["HOME"]= SDLK_HOME; + mKeys["UP"]= SDLK_UP; + mKeys["PGUP"]= SDLK_PAGEUP; + mKeys["LEFT"]= SDLK_LEFT; + mKeys["RIGHT"]= SDLK_RIGHT; + mKeys["END"]= SDLK_END; + mKeys["DOWN"]= SDLK_DOWN; + mKeys["PGDOWN"]= SDLK_PAGEDOWN; + mKeys["INSERT"]= SDLK_INSERT; + mKeys["DELETE"]= SDLK_DELETE; + + mKeys["NUMPADENTER"]= SDLK_KP_ENTER; + + for(std::map::iterator it = mKeys.begin() ; it != mKeys.end() ; it++) { mKeyCodes[ it->second ] = it->first; } } - std::string InputControlSystem::keyCodeToString(OIS::KeyCode key) + std::string InputControlSystem::keyCodeToString(SDL_Keycode key) { return mKeyCodes[key]; } - OIS::KeyCode InputControlSystem::stringToKeyCode(std::string key) + SDL_Keycode InputControlSystem::stringToKeyCode(std::string key) { return mKeys[key]; } -} \ No newline at end of file + + void InputControlSystem::adjustMouseRegion(Uint16 width, Uint16 height) + { + mClientWidth = width; + mClientHeight = height; + } +} diff --git a/extern/oics/ICSInputControlSystem.h b/extern/oics/ICSInputControlSystem.h index f1c12d3b5..5d30b35cf 100644 --- a/extern/oics/ICSInputControlSystem.h +++ b/extern/oics/ICSInputControlSystem.h @@ -32,6 +32,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "ICSControl.h" #include "ICSChannel.h" +#include "OISCompat.h" + #define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() ); #define ICS_MAX_JOYSTICK_AXIS 16 #define ICS_MOUSE_BINDING_MARGIN 30 @@ -48,9 +50,9 @@ namespace ICS }; class DllExport InputControlSystem : - public OIS::MouseListener, - public OIS::KeyListener, - public OIS::JoyStickListener + public MWSDLMouseListener, + public MWSDLKeyListener, + public MWSDLJoyStickListener { public: @@ -100,29 +102,30 @@ namespace ICS JoystickIDList& getJoystickIdList(){ return mJoystickIDList; }; // MouseListener - bool mouseMoved(const OIS::MouseEvent &evt); - bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID); - bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID); + bool mouseMoved(const MWSDLMouseMotionEvent &evt); + bool mousePressed(const SDL_MouseButtonEvent &evt, Uint8); + bool mouseReleased(const SDL_MouseButtonEvent &evt, Uint8); // KeyListener - bool keyPressed(const OIS::KeyEvent &evt); - bool keyReleased(const OIS::KeyEvent &evt); + bool keyPressed(const SDL_KeyboardEvent &evt); + bool keyReleased(const SDL_KeyboardEvent &evt); // JoyStickListener - bool buttonPressed(const OIS::JoyStickEvent &evt, int button); - bool buttonReleased(const OIS::JoyStickEvent &evt, int button); - bool axisMoved(const OIS::JoyStickEvent &evt, int axis); - bool povMoved(const OIS::JoyStickEvent &evt, int index); - bool sliderMoved(const OIS::JoyStickEvent &evt, int index); - - void addKeyBinding(Control* control, OIS::KeyCode key, Control::ControlChangingDirection direction); + bool buttonPressed(const SDL_JoyButtonEvent &evt, int button); + bool buttonReleased(const SDL_JoyButtonEvent &evt, int button); + bool axisMoved(const SDL_JoyAxisEvent &evt, int axis); + bool povMoved(const SDL_JoyHatEvent &evt, int index); + //TODO: does this have an SDL equivalent? + //bool sliderMoved(const OIS::JoyStickEvent &evt, int index); + + void addKeyBinding(Control* control, SDL_Keycode key, Control::ControlChangingDirection direction); void addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction); void addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction); void addJoystickAxisBinding(Control* control, int deviceId, int axis, Control::ControlChangingDirection direction); void addJoystickButtonBinding(Control* control, int deviceId, unsigned int button, Control::ControlChangingDirection direction); void addJoystickPOVBinding(Control* control, int deviceId, int index, POVAxis axis, Control::ControlChangingDirection direction); void addJoystickSliderBinding(Control* control, int deviceId, int index, Control::ControlChangingDirection direction); - void removeKeyBinding(OIS::KeyCode key); + void removeKeyBinding(SDL_Keycode key); void removeMouseAxisBinding(NamedAxis axis); void removeMouseButtonBinding(unsigned int button); void removeJoystickAxisBinding(int deviceId, int axis); @@ -130,7 +133,7 @@ namespace ICS void removeJoystickPOVBinding(int deviceId, int index, POVAxis axis); void removeJoystickSliderBinding(int deviceId, int index); - OIS::KeyCode getKeyBinding(Control* control, ICS::Control::ControlChangingDirection direction); + SDL_Keycode getKeyBinding(Control* control, ICS::Control::ControlChangingDirection direction); NamedAxis getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction); unsigned int getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction); int getJoystickAxisBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); @@ -138,14 +141,16 @@ namespace ICS POVBindingPair getJoystickPOVBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); int getJoystickSliderBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); - std::string keyCodeToString(OIS::KeyCode key); - OIS::KeyCode stringToKeyCode(std::string key); + std::string keyCodeToString(SDL_Keycode key); + SDL_Keycode stringToKeyCode(std::string key); void enableDetectingBindingState(Control* control, Control::ControlChangingDirection direction); void cancelDetectingBindingState(); bool save(std::string fileName = ""); + void adjustMouseRegion (Uint16 width, Uint16 height); + protected: void loadKeyBinders(TiXmlElement* xmlControlNode); @@ -180,7 +185,7 @@ namespace ICS std::string mFileName; - typedef std::map ControlsKeyBinderMapType; // + typedef std::map ControlsKeyBinderMapType; // typedef std::map ControlsAxisBinderMapType; // typedef std::map ControlsButtonBinderMapType; // typedef std::map ControlsPOVBinderMapType; // @@ -202,8 +207,8 @@ namespace ICS std::vector mChannels; ControlsKeyBinderMapType mControlsKeyBinderMap; - std::map mKeys; - std::map mKeyCodes; + std::map mKeys; + std::map mKeyCodes; bool mActive; InputControlSystemLog* mLog; @@ -221,14 +226,17 @@ namespace ICS private: - void fillOISKeysMap(); + void fillSDLKeysMap(); + + Uint16 mClientWidth; + Uint16 mClientHeight; }; class DllExport DetectingBindingListener { public: virtual void keyBindingDetected(InputControlSystem* ICS, Control* control - , OIS::KeyCode key, Control::ControlChangingDirection direction); + , SDL_Keycode key, Control::ControlChangingDirection direction); virtual void mouseAxisBindingDetected(InputControlSystem* ICS, Control* control , InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction); diff --git a/extern/oics/ICSInputControlSystem_joystick.cpp b/extern/oics/ICSInputControlSystem_joystick.cpp index 1e66599ea..8e501d501 100644 --- a/extern/oics/ICSInputControlSystem_joystick.cpp +++ b/extern/oics/ICSInputControlSystem_joystick.cpp @@ -26,6 +26,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "ICSInputControlSystem.h" +#define SDL_JOY_AXIS_MIN -32768 +#define SDL_JOY_AXIS_MAX 32767 + namespace ICS { // load xml @@ -315,16 +318,16 @@ namespace ICS } // joyStick listeners - bool InputControlSystem::buttonPressed(const OIS::JoyStickEvent &evt, int button) + bool InputControlSystem::buttonPressed(const SDL_JoyButtonEvent &evt, int button) { if(mActive) { if(!mDetectingBindingControl) { - if(mControlsJoystickButtonBinderMap.find(evt.device->getID()) != mControlsJoystickButtonBinderMap.end()) + if(mControlsJoystickButtonBinderMap.find(evt.which) != mControlsJoystickButtonBinderMap.end()) { - ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.device->getID()].find(button); - if(it != mControlsJoystickButtonBinderMap[evt.device->getID()].end()) + ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.which].find(button); + if(it != mControlsJoystickButtonBinderMap[evt.which].end()) { it->second.control->setIgnoreAutoReverse(false); if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) @@ -348,21 +351,21 @@ namespace ICS else if(mDetectingBindingListener) { mDetectingBindingListener->joystickButtonBindingDetected(this, - mDetectingBindingControl, evt.device->getID(), button, mDetectingBindingDirection); + mDetectingBindingControl, evt.which, button, mDetectingBindingDirection); } } return true; } - bool InputControlSystem::buttonReleased(const OIS::JoyStickEvent &evt, int button) + bool InputControlSystem::buttonReleased(const SDL_JoyButtonEvent &evt, int button) { if(mActive) { - if(mControlsJoystickButtonBinderMap.find(evt.device->getID()) != mControlsJoystickButtonBinderMap.end()) + if(mControlsJoystickButtonBinderMap.find(evt.which) != mControlsJoystickButtonBinderMap.end()) { - ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.device->getID()].find(button); - if(it != mControlsJoystickButtonBinderMap[evt.device->getID()].end()) + ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.which].find(button); + if(it != mControlsJoystickButtonBinderMap[evt.which].end()) { it->second.control->setChangingDirection(Control::STOP); } @@ -371,31 +374,29 @@ namespace ICS return true; } - bool InputControlSystem::axisMoved(const OIS::JoyStickEvent &evt, int axis) - { + bool InputControlSystem::axisMoved(const SDL_JoyAxisEvent &evt, int axis) + { if(mActive) { if(!mDetectingBindingControl) { - if(mControlsJoystickAxisBinderMap.find(evt.device->getID()) != mControlsJoystickAxisBinderMap.end()) + if(mControlsJoystickAxisBinderMap.find(evt.which) != mControlsJoystickAxisBinderMap.end()) { - ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.device->getID() ][ axis ]; // joystic axis start at 0 index + ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.which ][ axis ]; // joystic axis start at 0 index Control* ctrl = joystickBinderItem.control; if(ctrl) { ctrl->setIgnoreAutoReverse(true); + + float axisRange = SDL_JOY_AXIS_MAX - SDL_JOY_AXIS_MAX; + float valDisplaced = (float)(evt.value - SDL_JOY_AXIS_MIN); + if(joystickBinderItem.direction == Control::INCREASE) { - float axisRange = OIS::JoyStick::MAX_AXIS - OIS::JoyStick::MIN_AXIS; - float valDisplaced = (float)( evt.state.mAxes[axis].abs - OIS::JoyStick::MIN_AXIS); - ctrl->setValue( valDisplaced / axisRange ); } else if(joystickBinderItem.direction == Control::DECREASE) { - float axisRange = OIS::JoyStick::MAX_AXIS - OIS::JoyStick::MIN_AXIS; - float valDisplaced = (float)(evt.state.mAxes[axis].abs - OIS::JoyStick::MIN_AXIS); - ctrl->setValue( 1 - ( valDisplaced / axisRange ) ); } } @@ -403,15 +404,15 @@ namespace ICS } else if(mDetectingBindingListener) { - //ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.device->getID() ][ axis ]; // joystic axis start at 0 index + //ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.which ][ axis ]; // joystic axis start at 0 index //Control* ctrl = joystickBinderItem.control; //if(ctrl && ctrl->isAxisBindable()) if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) { - if( abs( evt.state.mAxes[axis].abs ) > ICS_JOYSTICK_AXIS_BINDING_MARGIN) + if( abs( evt.value ) > ICS_JOYSTICK_AXIS_BINDING_MARGIN) { mDetectingBindingListener->joystickAxisBindingDetected(this, - mDetectingBindingControl, evt.device->getID(), axis, mDetectingBindingDirection); + mDetectingBindingControl, evt.which, axis, mDetectingBindingDirection); } } } @@ -420,20 +421,21 @@ namespace ICS return true; } - bool InputControlSystem::povMoved(const OIS::JoyStickEvent &evt, int index) - { + //Here be dragons, apparently + bool InputControlSystem::povMoved(const SDL_JoyHatEvent &evt, int index) + { if(mActive) { if(!mDetectingBindingControl) { - if(mControlsJoystickPOVBinderMap.find(evt.device->getID()) != mControlsJoystickPOVBinderMap.end()) + if(mControlsJoystickPOVBinderMap.find(evt.which) != mControlsJoystickPOVBinderMap.end()) { - std::map::const_iterator i = mControlsJoystickPOVBinderMap[ evt.device->getID() ].find(index); - if(i != mControlsJoystickPOVBinderMap[ evt.device->getID() ].end()) + std::map::const_iterator i = mControlsJoystickPOVBinderMap[ evt.which ].find(index); + if(i != mControlsJoystickPOVBinderMap[ evt.which ].end()) { - if(evt.state.mPOV[index].direction != OIS::Pov::West - && evt.state.mPOV[index].direction != OIS::Pov::East - && evt.state.mPOV[index].direction != OIS::Pov::Centered) + if(evt.value != SDL_HAT_LEFT + && evt.value != SDL_HAT_RIGHT + && evt.value != SDL_HAT_CENTERED) { ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/NorthSouth ); if(it != i->second.end()) @@ -441,9 +443,9 @@ namespace ICS it->second.control->setIgnoreAutoReverse(false); if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) { - if(evt.state.mPOV[index].direction == OIS::Pov::North - || evt.state.mPOV[index].direction == OIS::Pov::NorthWest - || evt.state.mPOV[index].direction == OIS::Pov::NorthEast) + if(evt.value == SDL_HAT_UP + || evt.value == SDL_HAT_LEFTUP + || evt.value == SDL_HAT_RIGHTUP) { it->second.control->setChangingDirection(it->second.direction); } @@ -453,7 +455,7 @@ namespace ICS } } else - { + { if(it->second.control->getValue() == 1) { it->second.control->setChangingDirection(Control::DECREASE); @@ -466,9 +468,9 @@ namespace ICS } } - if(evt.state.mPOV[index].direction != OIS::Pov::North - && evt.state.mPOV[index].direction != OIS::Pov::South - && evt.state.mPOV[index].direction != OIS::Pov::Centered) + if(evt.value != SDL_HAT_UP + && evt.value != SDL_HAT_DOWN + && evt.value != SDL_HAT_CENTERED) { ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/EastWest ); if(it != i->second.end()) @@ -476,9 +478,9 @@ namespace ICS it->second.control->setIgnoreAutoReverse(false); if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) { - if(evt.state.mPOV[index].direction == OIS::Pov::East - || evt.state.mPOV[index].direction == OIS::Pov::NorthEast - || evt.state.mPOV[index].direction == OIS::Pov::SouthEast) + if(evt.value == SDL_HAT_RIGHT + || evt.value == SDL_HAT_RIGHTUP + || evt.value == SDL_HAT_RIGHTDOWN) { it->second.control->setChangingDirection(it->second.direction); } @@ -488,7 +490,7 @@ namespace ICS } } else - { + { if(it->second.control->getValue() == 1) { it->second.control->setChangingDirection(Control::DECREASE); @@ -501,7 +503,7 @@ namespace ICS } } - if(evt.state.mPOV[index].direction == OIS::Pov::Centered) + if(evt.value == SDL_HAT_CENTERED) { ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/NorthSouth ); if(it != i->second.end()) @@ -522,28 +524,30 @@ namespace ICS { if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) { - if(evt.state.mPOV[index].direction == OIS::Pov::West - || evt.state.mPOV[index].direction == OIS::Pov::East - || evt.state.mPOV[index].direction == OIS::Pov::North - || evt.state.mPOV[index].direction == OIS::Pov::South) + if(evt.value == SDL_HAT_LEFT + || evt.value == SDL_HAT_RIGHT + || evt.value == SDL_HAT_UP + || evt.value == SDL_HAT_DOWN) { POVAxis povAxis = NorthSouth; - if(evt.state.mPOV[index].direction == OIS::Pov::West - || evt.state.mPOV[index].direction == OIS::Pov::East) + if(evt.value == SDL_HAT_LEFT + || evt.value == SDL_HAT_RIGHT) { povAxis = EastWest; } mDetectingBindingListener->joystickPOVBindingDetected(this, - mDetectingBindingControl, evt.device->getID(), index, povAxis, mDetectingBindingDirection); + mDetectingBindingControl, evt.which, index, povAxis, mDetectingBindingDirection); } } } } - + return true; } + //TODO: does this have an SDL equivalent? + /* bool InputControlSystem::sliderMoved(const OIS::JoyStickEvent &evt, int index) { if(mActive) @@ -552,7 +556,7 @@ namespace ICS { if(mControlsJoystickSliderBinderMap.find(evt.device->getID()) != mControlsJoystickSliderBinderMap.end()) { - ControlSliderBinderItem joystickBinderItem = mControlsJoystickSliderBinderMap[ evt.device->getID() ][ index ]; + ControlSliderBinderItem joystickBinderItem = mControlsJoystickSliderBinderMap[ evt.device->getID() ][ index ]; Control* ctrl = joystickBinderItem.control; if(ctrl) { @@ -576,10 +580,6 @@ namespace ICS } else if(mDetectingBindingListener) { - /*ControlSliderBinderItem joystickBinderItem = mControlsJoystickSliderBinderMap[ evt.device->getID() ][ index ]; - Control* ctrl = joystickBinderItem.control; - if(ctrl && ctrl->isAxisBindable()) - {*/ if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) { if( abs( evt.state.mSliders[index].abX ) > ICS_JOYSTICK_SLIDER_BINDING_MARGIN) @@ -593,6 +593,7 @@ namespace ICS return true; } + */ // joystick auto bindings void DetectingBindingListener::joystickAxisBindingDetected(InputControlSystem* ICS, Control* control @@ -662,4 +663,4 @@ namespace ICS ICS->addJoystickSliderBinding(control, deviceId, slider, direction); ICS->cancelDetectingBindingState(); } -} \ No newline at end of file +} diff --git a/extern/oics/ICSInputControlSystem_keyboard.cpp b/extern/oics/ICSInputControlSystem_keyboard.cpp index 8ef81d979..01d68f784 100644 --- a/extern/oics/ICSInputControlSystem_keyboard.cpp +++ b/extern/oics/ICSInputControlSystem_keyboard.cpp @@ -49,7 +49,7 @@ namespace ICS } } - void InputControlSystem::addKeyBinding(Control* control, OIS::KeyCode key, Control::ControlChangingDirection direction) + void InputControlSystem::addKeyBinding(Control* control, SDL_Keycode key, Control::ControlChangingDirection direction) { ICS_LOG("\tAdding KeyBinder [key=" + keyCodeToString(key) + ", direction=" @@ -61,7 +61,7 @@ namespace ICS mControlsKeyBinderMap[ key ] = controlKeyBinderItem; } - void InputControlSystem::removeKeyBinding(OIS::KeyCode key) + void InputControlSystem::removeKeyBinding(SDL_Keycode key) { ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.find(key); if(it != mControlsKeyBinderMap.end()) @@ -70,7 +70,7 @@ namespace ICS } } - OIS::KeyCode InputControlSystem::getKeyBinding(Control* control + SDL_Keycode InputControlSystem::getKeyBinding(Control* control , ICS::Control::ControlChangingDirection direction) { ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.begin(); @@ -83,15 +83,15 @@ namespace ICS it++; } - return OIS::KC_UNASSIGNED; + return SDLK_UNKNOWN; } - bool InputControlSystem::keyPressed(const OIS::KeyEvent &evt) + bool InputControlSystem::keyPressed(const SDL_KeyboardEvent &evt) { if(mActive) { if(!mDetectingBindingControl) { - ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.key); + ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.keysym.sym); if(it != mControlsKeyBinderMap.end()) { it->second.control->setIgnoreAutoReverse(false); @@ -115,18 +115,18 @@ namespace ICS else if(mDetectingBindingListener) { mDetectingBindingListener->keyBindingDetected(this, - mDetectingBindingControl, evt.key, mDetectingBindingDirection); + mDetectingBindingControl, evt.keysym.sym, mDetectingBindingDirection); } } return true; } - bool InputControlSystem::keyReleased(const OIS::KeyEvent &evt) + bool InputControlSystem::keyReleased(const SDL_KeyboardEvent &evt) { if(mActive) { - ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.key); + ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.keysym.sym); if(it != mControlsKeyBinderMap.end()) { it->second.control->setChangingDirection(Control::STOP); @@ -137,14 +137,14 @@ namespace ICS } void DetectingBindingListener::keyBindingDetected(InputControlSystem* ICS, Control* control - , OIS::KeyCode key, Control::ControlChangingDirection direction) + , SDL_Keycode key, Control::ControlChangingDirection direction) { // if the key is used by another control, remove it ICS->removeKeyBinding(key); // if the control has a key assigned, remove it - OIS::KeyCode oldKey = ICS->getKeyBinding(control, direction); - if(oldKey != OIS::KC_UNASSIGNED) + SDL_Keycode oldKey = ICS->getKeyBinding(control, direction); + if(oldKey != SDLK_UNKNOWN) { ICS->removeKeyBinding(oldKey); } @@ -153,4 +153,4 @@ namespace ICS ICS->cancelDetectingBindingState(); } -} \ No newline at end of file +} diff --git a/extern/oics/ICSInputControlSystem_mouse.cpp b/extern/oics/ICSInputControlSystem_mouse.cpp index c62f1765e..96197426a 100644 --- a/extern/oics/ICSInputControlSystem_mouse.cpp +++ b/extern/oics/ICSInputControlSystem_mouse.cpp @@ -78,15 +78,15 @@ namespace ICS int button = 0; if(std::string(xmlMouseButtonBinder->Attribute("button")) == "LEFT") { - button = OIS::/*MouseButtonID::*/MB_Left; + button = SDL_BUTTON_LEFT; } else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "RIGHT") { - button = OIS::/*MouseButtonID::*/MB_Right; + button = SDL_BUTTON_RIGHT; } else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "MIDDLE") { - button = OIS::/*MouseButtonID::*/MB_Middle; + button = SDL_BUTTON_MIDDLE; } else { @@ -219,39 +219,39 @@ namespace ICS } // mouse Listeners - bool InputControlSystem::mouseMoved(const OIS::MouseEvent &evt) + bool InputControlSystem::mouseMoved(const MWSDLMouseMotionEvent& evt) { if(mActive) { if(!mDetectingBindingControl) { - if(mXmouseAxisBinded && evt.state.X.rel) + if(mXmouseAxisBinded && evt.xrel) { ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/X ]; Control* ctrl = mouseBinderItem.control; ctrl->setIgnoreAutoReverse(true); if(mouseBinderItem.direction == Control::INCREASE) { - ctrl->setValue( float( (evt.state.X.abs) / float(evt.state.width) ) ); + ctrl->setValue( float( (evt.x) / float(mClientWidth) ) ); } else if(mouseBinderItem.direction == Control::DECREASE) { - ctrl->setValue( 1 - float( evt.state.X.abs / float(evt.state.width) ) ); + ctrl->setValue( 1 - float( evt.x / float(mClientWidth) ) ); } } - if(mYmouseAxisBinded && evt.state.Y.rel) + if(mYmouseAxisBinded && evt.yrel) { ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/Y ]; Control* ctrl = mouseBinderItem.control; ctrl->setIgnoreAutoReverse(true); if(mouseBinderItem.direction == Control::INCREASE) { - ctrl->setValue( float( (evt.state.Y.abs) / float(evt.state.height) ) ); + ctrl->setValue( float( (evt.y) / float(mClientHeight) ) ); } else if(mouseBinderItem.direction == Control::DECREASE) { - ctrl->setValue( 1 - float( evt.state.Y.abs / float(evt.state.height) ) ); + ctrl->setValue( 1 - float( evt.y / float(mClientHeight) ) ); } } @@ -282,9 +282,9 @@ namespace ICS mMouseAxisBindingInitialValues[2] = 0; } - mMouseAxisBindingInitialValues[0] += evt.state.X.rel; - mMouseAxisBindingInitialValues[1] += evt.state.Y.rel; - mMouseAxisBindingInitialValues[2] += evt.state.Z.rel; + mMouseAxisBindingInitialValues[0] += evt.xrel; + mMouseAxisBindingInitialValues[1] += evt.yrel; + mMouseAxisBindingInitialValues[2] += evt.zrel; if( abs(mMouseAxisBindingInitialValues[0]) > ICS_MOUSE_BINDING_MARGIN ) { @@ -308,7 +308,7 @@ namespace ICS return true; } - bool InputControlSystem::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID btn) + bool InputControlSystem::mousePressed(const SDL_MouseButtonEvent &evt, Uint8 btn) { if(mActive) { @@ -345,7 +345,7 @@ namespace ICS return true; } - bool InputControlSystem::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID btn) + bool InputControlSystem::mouseReleased(const SDL_MouseButtonEvent &evt, Uint8 btn) { if(mActive) { @@ -394,4 +394,4 @@ namespace ICS ICS->cancelDetectingBindingState(); } -} \ No newline at end of file +} diff --git a/extern/oics/ICSPrerequisites.h b/extern/oics/ICSPrerequisites.h index 3b5d1935b..82c95c86a 100644 --- a/extern/oics/ICSPrerequisites.h +++ b/extern/oics/ICSPrerequisites.h @@ -39,11 +39,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tinyxml.h" -#include -#include -#include -#include -#include +#include "SDL2/SDL_input.h" +#include "SDL2/SDL_keyboard.h" +#include "SDL2/SDL_mouse.h" +#include "SDL2/SDL_joystick.h" +#include "SDL2/SDL_events.h" /// Define the dll export qualifier if compiling for Windows @@ -65,8 +65,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /// Version defines #define ICS_VERSION_MAJOR 0 -#define ICS_VERSION_MINOR 3 -#define ICS_VERSION_PATCH 1 +#define ICS_VERSION_MINOR 4 +#define ICS_VERSION_PATCH 0 #define ICS_MAX_DEVICE_BUTTONS 30 diff --git a/extern/oics/OISCompat.h b/extern/oics/OISCompat.h new file mode 100644 index 000000000..18bdd6bae --- /dev/null +++ b/extern/oics/OISCompat.h @@ -0,0 +1,90 @@ +#ifndef _OIS_SDL_COMPAT_H +#define _OIS_SDL_COMPAT_H + +#include +#include + +//TODO: Remove this. Right now we want to remain as close to OIS as possible +//So we can easily test the SDL backend + +//////////// +// Events // +//////////// + +namespace ICS { + +/** Extended mouse event struct where we treat the wheel like an axis, like everyone expects */ +struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent { + + Sint16 zrel; + + MWSDLMouseMotionEvent() + { + x = 0; + y = 0; + xrel = 0; + yrel = 0; + state = 0; + zrel = 0; + } + + MWSDLMouseMotionEvent( const SDL_MouseMotionEvent& evt) : + MWSDLMouseMotionEvent() + { + x = evt.x; + y = evt.y; + xrel = evt.xrel; + yrel = evt.yrel; + state = evt.state; + } + + MWSDLMouseMotionEvent (const SDL_MouseWheelEvent& evt) : + MWSDLMouseMotionEvent() + { + zrel = evt.y; + } +}; + + +/////////////// +// Listeners // +/////////////// + +class MWSDLMouseListener +{ +public: + virtual ~MWSDLMouseListener() {} + virtual bool mouseMoved( const MWSDLMouseMotionEvent &arg ) = 0; + virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0; + virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0; +}; + +class MWSDLKeyListener +{ +public: + virtual ~MWSDLKeyListener() {} + virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0; + virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0; +}; + +class MWSDLJoyStickListener +{ +public: + virtual ~MWSDLJoyStickListener() {} + /** @remarks Joystick button down event */ + virtual bool buttonPressed( const SDL_JoyButtonEvent &evt, int button ) = 0; + + /** @remarks Joystick button up event */ + virtual bool buttonReleased( const SDL_JoyButtonEvent &evt, int button ) = 0; + + /** @remarks Joystick axis moved event */ + virtual bool axisMoved( const SDL_JoyAxisEvent &arg, int axis ) = 0; + + //-- Not so common control events, so are not required --// + + //! Joystick Event, and povID + virtual bool povMoved( const SDL_JoyHatEvent &arg, int index) {return true;} +}; + +} +#endif From 3b1d285cf3898dfaee3336836e81403f379fde75 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Tue, 8 Jan 2013 21:01:58 -0400 Subject: [PATCH 002/213] fix compile errors, work with unmodified SDL --- apps/openmw/mwinput/sdlinputwrapper.cpp | 50 ++++++++++++++++++++++++- extern/oics/OISCompat.h | 22 +++++++---- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwinput/sdlinputwrapper.cpp b/apps/openmw/mwinput/sdlinputwrapper.cpp index 60c7e8f7a..61fc3fc8b 100644 --- a/apps/openmw/mwinput/sdlinputwrapper.cpp +++ b/apps/openmw/mwinput/sdlinputwrapper.cpp @@ -1,5 +1,15 @@ #include "sdlinputwrapper.hpp" #include +#include + +#include + +#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX +# include +# include +# include +#endif + namespace MWInput { @@ -62,9 +72,45 @@ namespace MWInput size_t windowHnd; mWindow->getCustomAttribute("WINDOW", &windowHnd); - //just use that one for input - SDL_Init(flags); + //kindly ask SDL not to trash our OGL context + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); + SDL_Init(SDL_INIT_VIDEO); + + //wrap our own event handler around ogre's mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); + +#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX + //linux-specific event-handling fixups + SDL_SysWMinfo wm_info; + SDL_VERSION(&wm_info.version); + + if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info)) + { + printf("SDL version %d.%d.%d\n", wm_info.version.major, wm_info.version.minor, wm_info.version.patch); + + Display* display = wm_info.info.x11.display; + Window w = wm_info.info.x11.window; + + // Set the input hints so we get keyboard input + XWMHints *wmhints = XAllocWMHints(); + if (wmhints) { + wmhints->input = True; + wmhints->flags = InputHint; + XSetWMHints(display, w, wmhints); + XFree(wmhints); + } + + //make sure to subscribe to XLib's events + XSelectInput(display, w, + (FocusChangeMask | EnterWindowMask | LeaveWindowMask | + ExposureMask | ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | KeyPressMask | KeyReleaseMask | + PropertyChangeMask | StructureNotifyMask | + KeymapStateMask)); + + XFlush(display); + } +#endif } } } diff --git a/extern/oics/OISCompat.h b/extern/oics/OISCompat.h index 18bdd6bae..74b6acde1 100644 --- a/extern/oics/OISCompat.h +++ b/extern/oics/OISCompat.h @@ -20,17 +20,12 @@ struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent { MWSDLMouseMotionEvent() { - x = 0; - y = 0; - xrel = 0; - yrel = 0; - state = 0; - zrel = 0; + _init(); } - MWSDLMouseMotionEvent( const SDL_MouseMotionEvent& evt) : - MWSDLMouseMotionEvent() + MWSDLMouseMotionEvent( const SDL_MouseMotionEvent& evt) { + _init(); x = evt.x; y = evt.y; xrel = evt.xrel; @@ -41,8 +36,19 @@ struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent { MWSDLMouseMotionEvent (const SDL_MouseWheelEvent& evt) : MWSDLMouseMotionEvent() { + _init(); zrel = evt.y; } + + void _init() + { + x = 0; + y = 0; + xrel = 0; + yrel = 0; + state = 0; + zrel = 0; + } }; From 00a2a5c358e8a4ee189f92f7b0423605b3a308a2 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Tue, 8 Jan 2013 21:04:36 -0400 Subject: [PATCH 003/213] remove some more of my mess --- extern/oics/OISCompat.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extern/oics/OISCompat.h b/extern/oics/OISCompat.h index 74b6acde1..e8fd6904c 100644 --- a/extern/oics/OISCompat.h +++ b/extern/oics/OISCompat.h @@ -33,8 +33,7 @@ struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent { state = evt.state; } - MWSDLMouseMotionEvent (const SDL_MouseWheelEvent& evt) : - MWSDLMouseMotionEvent() + MWSDLMouseMotionEvent (const SDL_MouseWheelEvent& evt) { _init(); zrel = evt.y; From 6b49b8ab47e4dcbd363a3ae281b55026c2b5759a Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Tue, 8 Jan 2013 22:14:30 -0400 Subject: [PATCH 004/213] MyGUI doesn't care for SDL's mouse button ordering, send it what it expects --- apps/openmw/mwinput/inputmanagerimp.cpp | 16 ++++++++++++++-- apps/openmw/mwinput/inputmanagerimp.hpp | 6 ++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 9524381fb..f13eb9daf 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -450,7 +450,7 @@ namespace MWInput { mInputCtrl->mousePressed (arg, id); - MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, MyGUI::MouseButton::Enum(id)); + MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)); if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) { @@ -468,7 +468,7 @@ namespace MWInput { mInputCtrl->mouseReleased (arg, id); - MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, MyGUI::MouseButton::Enum(id)); + MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)); return true; } @@ -905,4 +905,16 @@ namespace MWInput { loadKeyDefaults(true); } + + MyGUI::MouseButton InputManager::sdlButtonToMyGUI(Uint8 button) + { + //The right button is the second button, according to MyGUI + if(button == SDL_BUTTON_RIGHT) + button = SDL_BUTTON_MIDDLE; + else if(button == SDL_BUTTON_MIDDLE) + button = SDL_BUTTON_RIGHT; + + //MyGUI's buttons are 0 indexed + return MyGUI::MouseButton::Enum(button - 1); + } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 3677f9070..df6ce3c43 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -36,6 +36,11 @@ namespace ICS class InputControlSystem; } +namespace MyGUI +{ + class MouseButton; +} + #include #include #include @@ -149,6 +154,7 @@ namespace MWInput private: void adjustMouseRegion(int width, int height); + MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button); void resetIdleTime(); void updateIdleTime(float dt); From 1bf36c686c5fd2c85eff2be5e08933a48df79c20 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Wed, 9 Jan 2013 06:09:47 -0400 Subject: [PATCH 005/213] add ability to check if a window is on the stack (to see if we're in the main menu) --- apps/openmw/mwbase/windowmanager.hpp | 1 + apps/openmw/mwgui/windowmanagerimp.cpp | 8 ++++++++ apps/openmw/mwgui/windowmanagerimp.hpp | 1 + 3 files changed, 10 insertions(+) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 30bfced06..13a35b592 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -88,6 +88,7 @@ namespace MWBase ///< can be anywhere in the stack virtual MWGui::GuiMode getMode() const = 0; + virtual bool containsMode(MWGui::GuiMode) const = 0; virtual bool isGuiMode() const = 0; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 8ec495550..d653b578a 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -965,6 +965,14 @@ MWGui::GuiMode WindowManager::getMode() const return mGuiModes.back(); } +bool WindowManager::containsMode(GuiMode mode) const +{ + if(mGuiModes.empty()) + return false; + + return std::find(mGuiModes.begin(), mGuiModes.end(), mode) != mGuiModes.end(); +} + std::map > WindowManager::getPlayerSkillValues() { return mPlayerSkillValues; diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 8bcb88e22..e2a966660 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -97,6 +97,7 @@ namespace MWGui virtual void removeGuiMode(GuiMode mode); ///< can be anywhere in the stack virtual GuiMode getMode() const; + virtual bool containsMode(GuiMode mode) const; virtual bool isGuiMode() const; From 02ccb758949b64abe026766e141a562d53313feb Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Wed, 9 Jan 2013 06:10:05 -0400 Subject: [PATCH 006/213] Wrap the mouse to the window (except in debug mode) Grab the mouse when not in the main menu (except in debug mode) Always hide the cursor when it's over the window Allow warping the mouse around Handle ^C properly --- apps/openmw/mwinput/inputmanagerimp.cpp | 75 +++++------ apps/openmw/mwinput/inputmanagerimp.hpp | 5 + apps/openmw/mwinput/sdlinputwrapper.cpp | 170 ++++++++++++++++++------ apps/openmw/mwinput/sdlinputwrapper.hpp | 22 ++- extern/oics/OISCompat.h | 12 ++ 5 files changed, 194 insertions(+), 90 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index f13eb9daf..805f4926c 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -44,6 +44,7 @@ namespace MWInput , mUserFile(userFile) , mDragDrop(false) , mGuiCursorEnabled(false) + , mDebug(debug) , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input")) @@ -52,50 +53,6 @@ namespace MWInput , mPreviewPOVDelay(0.f) , mTimeIdle(0.f) { - Ogre::RenderWindow* window = ogre.getWindow (); - size_t windowHnd; - - resetIdleTime(); - - window->getCustomAttribute("WINDOW", &windowHnd); - - - // Set non-exclusive mouse and keyboard input if the user requested - // it. - - //TODO: re-enable this and make it work with SDL - /* - - std::ostringstream windowHndStr; - OIS::ParamList pl; - - windowHndStr << windowHnd; - pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); - - if (debug) - { - #if defined OIS_WIN32_PLATFORM - pl.insert(std::make_pair(std::string("w32_mouse"), - std::string("DISCL_FOREGROUND" ))); - pl.insert(std::make_pair(std::string("w32_mouse"), - std::string("DISCL_NONEXCLUSIVE"))); - pl.insert(std::make_pair(std::string("w32_keyboard"), - std::string("DISCL_FOREGROUND"))); - pl.insert(std::make_pair(std::string("w32_keyboard"), - std::string("DISCL_NONEXCLUSIVE"))); - #elif defined OIS_LINUX_PLATFORM - pl.insert(std::make_pair(std::string("x11_mouse_grab"), - std::string("false"))); - pl.insert(std::make_pair(std::string("x11_mouse_hide"), - std::string("false"))); - pl.insert(std::make_pair(std::string("x11_keyboard_grab"), - std::string("false"))); - pl.insert(std::make_pair(std::string("XAutoRepeatOn"), - std::string("true"))); - #endif - } - */ - #if defined(__APPLE__) && !defined(__LP64__) // Give the application window focus to receive input events ProcessSerialNumber psn = { 0, kCurrentProcess }; @@ -103,9 +60,12 @@ namespace MWInput SetFrontProcess(&psn); #endif + Ogre::RenderWindow* window = ogre.getWindow (); + mInputManager = new MWSDLInputWrapper(window); mInputManager->setMouseEventCallback (this); mInputManager->setKeyboardEventCallback (this); + mInputManager->setWindowEventCallback(this); std::string file = userFileExists ? userFile : ""; mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); @@ -256,6 +216,15 @@ namespace MWInput // event callbacks (which may crash) mWindows.update(); + if(!mDebug) + { + //don't keep the pointer away from the window edge in GUI mode + mInputManager->setWrapPointer(!mWindows.isGuiMode()); + + //we let the mouse escape in the main menu + mInputManager->setGrabPointer(!mWindows.containsMode(MWGui::GM_MainMenu)); + } + // Disable movement in Gui mode if (mWindows.isGuiMode()) return; @@ -510,6 +479,24 @@ namespace MWInput return true; } + bool InputManager::windowFocusChange(bool have_focus) + { + if(!mDebug) + { + + } + return true; + } + + bool InputManager::windowVisibilityChange(bool visible) + { + if(!mDebug) + { + //TODO: Pause game? + } + return true; + } + void InputManager::toggleMainMenu() { if (mWindows.isGuiMode () && (mWindows.getMode () == MWGui::GM_MainMenu || mWindows.getMode () == MWGui::GM_Settings)) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index df6ce3c43..9a7656a67 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -55,6 +55,7 @@ namespace MWInput public MWBase::InputManager, public ICS::MWSDLKeyListener, public ICS::MWSDLMouseListener, + public ICS::MWSDLWindowListener, public ICS::ChannelListener, public ICS::DetectingBindingListener { @@ -94,6 +95,9 @@ namespace MWInput virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ); virtual bool mouseMoved( const ICS::MWSDLMouseMotionEvent &arg ); + virtual bool windowVisibilityChange( bool visible ); + virtual bool windowFocusChange( bool have_focus ); + virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue); virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control @@ -145,6 +149,7 @@ namespace MWInput bool mMouseLookEnabled; bool mGuiCursorEnabled; + bool mDebug; float mMouseX; float mMouseY; diff --git a/apps/openmw/mwinput/sdlinputwrapper.cpp b/apps/openmw/mwinput/sdlinputwrapper.cpp index 61fc3fc8b..c8922cf3a 100644 --- a/apps/openmw/mwinput/sdlinputwrapper.cpp +++ b/apps/openmw/mwinput/sdlinputwrapper.cpp @@ -3,6 +3,7 @@ #include #include +#include #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX # include @@ -14,7 +15,11 @@ namespace MWInput { MWSDLInputWrapper::MWSDLInputWrapper(Ogre::RenderWindow *window) : - mWindow(window), mStarted(false), mSDLWindow(NULL) + mWindow(window), + mSDLWindow(NULL), + mWarpCompensate(false), + mWrapPointer(false), + mGrabPointer(false) { _start(); } @@ -26,44 +31,7 @@ namespace MWInput SDL_Quit(); } - void MWSDLInputWrapper::capture() - { - _start(); - - SDL_Event evt; - while(SDL_PollEvent(&evt)) - { - switch(evt.type) - { - case SDL_MOUSEMOTION: - mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.motion)); - break; - case SDL_MOUSEWHEEL: - mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.wheel)); - break; - case SDL_MOUSEBUTTONDOWN: - mMouseListener->mousePressed(evt.button, evt.button.button); - break; - case SDL_MOUSEBUTTONUP: - mMouseListener->mouseReleased(evt.button, evt.button.button); - break; - - case SDL_KEYDOWN: - mKeyboardListener->keyPressed(evt.key); - break; - case SDL_KEYUP: - mKeyboardListener->keyReleased(evt.key); - break; - } - } - } - - bool MWSDLInputWrapper::isModifierHeld(int mod) - { - return SDL_GetModState() & mod; - } - - void MWSDLInputWrapper::_start() + bool MWSDLInputWrapper::_start() { Uint32 flags = SDL_INIT_VIDEO; if(SDL_WasInit(flags) == 0) @@ -74,11 +42,15 @@ namespace MWInput //kindly ask SDL not to trash our OGL context SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); - SDL_Init(SDL_INIT_VIDEO); + if(SDL_Init(SDL_INIT_VIDEO) != 0) + return false; //wrap our own event handler around ogre's mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); + if(mSDLWindow == NULL) + return false; + #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX //linux-specific event-handling fixups SDL_SysWMinfo wm_info; @@ -86,8 +58,6 @@ namespace MWInput if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info)) { - printf("SDL version %d.%d.%d\n", wm_info.version.major, wm_info.version.minor, wm_info.version.patch); - Display* display = wm_info.info.x11.display; Window w = wm_info.info.x11.window; @@ -111,6 +81,122 @@ namespace MWInput XFlush(display); } #endif + SDL_ShowCursor(SDL_FALSE); + } + + return true; + } + + void MWSDLInputWrapper::capture() + { + if(!_start()) + throw std::runtime_error(SDL_GetError()); + + SDL_Event evt; + while(SDL_PollEvent(&evt)) + { + switch(evt.type) + { + case SDL_MOUSEMOTION: + //ignore this if it happened due to a warp + if(!_handleWarpMotion(evt.motion)) + { + mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.motion)); + + //try to keep the mouse inside the window + _wrapMousePointer(evt.motion); + } + break; + case SDL_MOUSEWHEEL: + mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.wheel)); + break; + case SDL_MOUSEBUTTONDOWN: + mMouseListener->mousePressed(evt.button, evt.button.button); + break; + case SDL_MOUSEBUTTONUP: + mMouseListener->mouseReleased(evt.button, evt.button.button); + break; + + case SDL_KEYDOWN: + mKeyboardListener->keyPressed(evt.key); + break; + case SDL_KEYUP: + mKeyboardListener->keyReleased(evt.key); + break; + + case SDL_WINDOWEVENT_FOCUS_GAINED: + mWindowListener->windowFocusChange(true); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + mWindowListener->windowFocusChange(false); + break; + case SDL_WINDOWEVENT_EXPOSED: + mWindowListener->windowVisibilityChange(true); + break; + case SDL_WINDOWEVENT_HIDDEN: + mWindowListener->windowVisibilityChange(false); + break; + + //SDL traps ^C signals, pass it to OGRE. + case SDL_QUIT: + Ogre::Root::getSingleton().queueEndRendering(); + break; + } + } + } + + bool MWSDLInputWrapper::isModifierHeld(int mod) + { + return SDL_GetModState() & mod; + } + + void MWSDLInputWrapper::warpMouse(int x, int y) + { + SDL_WarpMouseInWindow(mSDLWindow, x, y); + mWarpCompensate = true; + mWarpX = x; + mWarpY = y; + } + + void MWSDLInputWrapper::setGrabPointer(bool grab) + { + SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE; + + mGrabPointer = grab; + SDL_SetWindowGrab(mSDLWindow, sdlGrab); + } + + bool MWSDLInputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt) + { + if(!mWarpCompensate) return false; + + //this was a warp event, signal the caller to eat it. + if(evt.x == mWarpX && evt.y == mWarpY) + { + mWarpCompensate = false; + return true; + } + + return false; + } + + void MWSDLInputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt) + { + if(!mWrapPointer || !mGrabPointer) return; + + int width = 0; + int height = 0; + + SDL_GetWindowSize(mSDLWindow, &width, &height); + + const int FUDGE_FACTOR_X = width / 4; + const int FUDGE_FACTOR_Y = height / 4; + + //warp the mouse if it's about to go outside the window + if(evt.x - FUDGE_FACTOR_X < 0 || evt.x + FUDGE_FACTOR_X > width + || evt.y - FUDGE_FACTOR_Y < 0 || evt.y + FUDGE_FACTOR_Y > height) + { + warpMouse(width / 2, height / 2); } } } diff --git a/apps/openmw/mwinput/sdlinputwrapper.hpp b/apps/openmw/mwinput/sdlinputwrapper.hpp index ee07efbdb..d507073b8 100644 --- a/apps/openmw/mwinput/sdlinputwrapper.hpp +++ b/apps/openmw/mwinput/sdlinputwrapper.hpp @@ -16,19 +16,33 @@ namespace MWInput void setMouseEventCallback(ICS::MWSDLMouseListener* listen) { mMouseListener = listen; } void setKeyboardEventCallback(ICS::MWSDLKeyListener* listen) { mKeyboardListener = listen; } + void setWindowEventCallback(ICS::MWSDLWindowListener* listen) { mWindowListener = listen; } void capture(); bool isModifierHeld(int mod); + void setWrapPointer(bool wrap) { mWrapPointer = wrap; } + void setGrabPointer(bool grab); + + void warpMouse(int x, int y); private: + bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); + void _wrapMousePointer(const SDL_MouseMotionEvent &evt); + + bool _start(); + ICS::MWSDLMouseListener* mMouseListener; ICS::MWSDLKeyListener* mKeyboardListener; - Ogre::RenderWindow* mWindow; - SDL_Window* mSDLWindow; + ICS::MWSDLWindowListener* mWindowListener; - bool mStarted; - void _start(); + Uint16 mWarpX; + Uint16 mWarpY; + bool mWarpCompensate; + bool mWrapPointer; + bool mGrabPointer; + Ogre::RenderWindow* mWindow; + SDL_Window* mSDLWindow; }; } diff --git a/extern/oics/OISCompat.h b/extern/oics/OISCompat.h index e8fd6904c..5813c17bf 100644 --- a/extern/oics/OISCompat.h +++ b/extern/oics/OISCompat.h @@ -91,5 +91,17 @@ public: virtual bool povMoved( const SDL_JoyHatEvent &arg, int index) {return true;} }; +class MWSDLWindowListener +{ +public: + virtual ~MWSDLWindowListener() {} + + /** @remarks The window's visibility changed */ + virtual bool windowVisibilityChange( bool visible ) = 0; + + /** @remarks The window got / lost input focus */ + virtual bool windowFocusChange( bool have_focus ) = 0; +}; + } #endif From 53cff0ba68f72d49834c9effbf1771a05a9d9a42 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Wed, 9 Jan 2013 09:05:47 -0400 Subject: [PATCH 007/213] use native relative mouse movements where available, have the cursor follow the hardware cursor in the main menu --- apps/openmw/mwinput/inputmanagerimp.cpp | 40 ++++++++++++++++++++----- apps/openmw/mwinput/sdlinputwrapper.cpp | 37 ++++++++++++++++++++--- apps/openmw/mwinput/sdlinputwrapper.hpp | 4 ++- 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 805f4926c..17251aff5 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -218,11 +218,23 @@ namespace MWInput if(!mDebug) { - //don't keep the pointer away from the window edge in GUI mode - mInputManager->setWrapPointer(!mWindows.isGuiMode()); + bool main_menu = mWindows.containsMode(MWGui::GM_MainMenu); + + bool was_relative = mInputManager->getMouseRelative(); + bool is_relative = !main_menu; + + //don't keep the pointer away from the window edge in the main menu + mInputManager->setMouseRelative(is_relative); + + //we switched to non-relative mode, move our cursor to where the in-game + //cursor is + if( !is_relative && was_relative != is_relative ) + { + mInputManager->warpMouse(mMouseX, mMouseY); + } //we let the mouse escape in the main menu - mInputManager->setGrabPointer(!mWindows.containsMode(MWGui::GM_MainMenu)); + mInputManager->setGrabPointer(!main_menu); } // Disable movement in Gui mode @@ -454,8 +466,19 @@ namespace MWInput // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor - mMouseX += float(arg.xrel) * mUISensitivity; - mMouseY += float(arg.yrel) * mUISensitivity * mUIYMultiplier; + + //FIXME: Except in the main menu, since we let the pointer escape + if(!mWindows.containsMode(MWGui::GM_MainMenu)) + { + mMouseX += float(arg.xrel) * mUISensitivity; + mMouseY += float(arg.yrel) * mUISensitivity * mUIYMultiplier; + } + else + { + mMouseX = arg.x; + mMouseY = arg.y; + } + mMouseX = std::max(0.f, std::min(mMouseX, float(viewSize.width))); mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height))); @@ -499,10 +522,11 @@ namespace MWInput void InputManager::toggleMainMenu() { - if (mWindows.isGuiMode () && (mWindows.getMode () == MWGui::GM_MainMenu || mWindows.getMode () == MWGui::GM_Settings)) - mWindows.popGuiMode(); - else if (mWindows.isGuiMode () && mWindows.getMode () == MWGui::GM_Video) + //TODO: should this be here? + if (mWindows.isGuiMode () && mWindows.getMode () == MWGui::GM_Video) MWBase::Environment::get().getWorld ()->stopVideo (); + else if (mWindows.containsMode(MWGui::GM_MainMenu)) + mWindows.popGuiMode(); else mWindows.pushGuiMode (MWGui::GM_MainMenu); } diff --git a/apps/openmw/mwinput/sdlinputwrapper.cpp b/apps/openmw/mwinput/sdlinputwrapper.cpp index c8922cf3a..32f453b0f 100644 --- a/apps/openmw/mwinput/sdlinputwrapper.cpp +++ b/apps/openmw/mwinput/sdlinputwrapper.cpp @@ -18,8 +18,9 @@ namespace MWInput mWindow(window), mSDLWindow(NULL), mWarpCompensate(false), - mWrapPointer(false), - mGrabPointer(false) + mMouseRelative(false), + mGrabPointer(false), + mWrapPointer(false) { _start(); } @@ -166,9 +167,34 @@ namespace MWInput SDL_SetWindowGrab(mSDLWindow, sdlGrab); } + void MWSDLInputWrapper::setMouseRelative(bool relative) + { + if(mMouseRelative == relative) + return; + + mMouseRelative = relative; + + mWrapPointer = false; + + //eep, wrap the pointer manually if the input driver doesn't support + //relative positioning natively + if(SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == -1) + { + if(relative) + mWrapPointer = true; + } + + //now remove all mouse events using the old setting from the queue + SDL_PumpEvents(); + + SDL_Event dummy[20]; + SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION); + } + bool MWSDLInputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt) { - if(!mWarpCompensate) return false; + if(!mWarpCompensate) + return false; //this was a warp event, signal the caller to eat it. if(evt.x == mWarpX && evt.y == mWarpY) @@ -182,7 +208,10 @@ namespace MWInput void MWSDLInputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt) { - if(!mWrapPointer || !mGrabPointer) return; + //don't wrap if we don't want relative movements, support relative + //movements natively, or aren't grabbing anyways + if(!mMouseRelative || !mWrapPointer || !mGrabPointer) + return; int width = 0; int height = 0; diff --git a/apps/openmw/mwinput/sdlinputwrapper.hpp b/apps/openmw/mwinput/sdlinputwrapper.hpp index d507073b8..c2770ae7e 100644 --- a/apps/openmw/mwinput/sdlinputwrapper.hpp +++ b/apps/openmw/mwinput/sdlinputwrapper.hpp @@ -21,7 +21,8 @@ namespace MWInput void capture(); bool isModifierHeld(int mod); - void setWrapPointer(bool wrap) { mWrapPointer = wrap; } + void setMouseRelative(bool relative); + bool getMouseRelative() { return mMouseRelative; } void setGrabPointer(bool grab); void warpMouse(int x, int y); @@ -38,6 +39,7 @@ namespace MWInput Uint16 mWarpX; Uint16 mWarpY; bool mWarpCompensate; + bool mMouseRelative; bool mWrapPointer; bool mGrabPointer; From cb01df49c01f8e1391c62d3a1fd0a64b51bc81ff Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Wed, 9 Jan 2013 11:30:33 -0400 Subject: [PATCH 008/213] begin to support text input --- apps/openmw/mwinput/inputmanagerimp.cpp | 1 + apps/openmw/mwinput/sdlinputwrapper.cpp | 27 +++++++++++++++++++++++-- apps/openmw/mwinput/sdlinputwrapper.hpp | 2 ++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 17251aff5..763e75ae7 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -413,6 +413,7 @@ namespace MWInput } #endif */ + MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.keysym.sym), text); return true; diff --git a/apps/openmw/mwinput/sdlinputwrapper.cpp b/apps/openmw/mwinput/sdlinputwrapper.cpp index 32f453b0f..56b3568f5 100644 --- a/apps/openmw/mwinput/sdlinputwrapper.cpp +++ b/apps/openmw/mwinput/sdlinputwrapper.cpp @@ -27,8 +27,10 @@ namespace MWInput MWSDLInputWrapper::~MWSDLInputWrapper() { - SDL_DestroyWindow(mSDLWindow); + if(mSDLWindow != NULL) + SDL_DestroyWindow(mSDLWindow); mSDLWindow = NULL; + SDL_StopTextInput(); SDL_Quit(); } @@ -52,6 +54,8 @@ namespace MWInput if(mSDLWindow == NULL) return false; + SDL_StartTextInput(); + #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX //linux-specific event-handling fixups SDL_SysWMinfo wm_info; @@ -119,7 +123,7 @@ namespace MWInput break; case SDL_KEYDOWN: - mKeyboardListener->keyPressed(evt.key); + _handleKeyPress(evt.key); break; case SDL_KEYUP: mKeyboardListener->keyReleased(evt.key); @@ -228,4 +232,23 @@ namespace MWInput warpMouse(width / 2, height / 2); } } + + void MWSDLInputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt) + { + //SDL keyboard events are followed by the actual text those keys would generate + //to account for languages that require multiple keystrokes to produce a key. + //Look for an event immediately following ours, assuming each key produces exactly + //one character. + + //TODO: This won't work for multibyte characters, but MyGUI is the only consumer + //of these, does it even support multibyte characters? + + SDL_Event text_evts[1]; + if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0) + { + evt.keysym.unicode = text_evts[0].text.text[0]; + } + + mKeyboardListener->keyPressed(evt); + } } diff --git a/apps/openmw/mwinput/sdlinputwrapper.hpp b/apps/openmw/mwinput/sdlinputwrapper.hpp index c2770ae7e..6377d0bcf 100644 --- a/apps/openmw/mwinput/sdlinputwrapper.hpp +++ b/apps/openmw/mwinput/sdlinputwrapper.hpp @@ -30,6 +30,8 @@ namespace MWInput bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); void _wrapMousePointer(const SDL_MouseMotionEvent &evt); + void _handleKeyPress(SDL_KeyboardEvent& evt); + bool _start(); ICS::MWSDLMouseListener* mMouseListener; From ed644259ce71df3a3c61e54d8f92ebf6bfedfe14 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Thu, 10 Jan 2013 17:21:47 -0400 Subject: [PATCH 009/213] Move SDL helpers to their own package in extern/, allow conversion from sdl to ois keycodes, (maybe) fix unicode handling --- CMakeLists.txt | 1 + apps/openmw/CMakeLists.txt | 3 +- apps/openmw/mwinput/inputmanagerimp.cpp | 76 ++-- apps/openmw/mwinput/inputmanagerimp.hpp | 15 +- apps/openmw/mwinput/sdlinputwrapper.cpp | 254 ----------- apps/openmw/mwinput/sdlinputwrapper.hpp | 53 --- extern/oics/CMakeLists.txt | 1 - extern/oics/ICSInputControlSystem.h | 10 +- extern/oics/ICSInputControlSystem_mouse.cpp | 2 +- extern/sdl4ogre/CMakeLists.txt | 14 + extern/sdl4ogre/OISCompat.h | 159 +++++++ .../{oics/OISCompat.h => sdl4ogre/events.h} | 68 +-- extern/sdl4ogre/sdlinputwrapper.cpp | 420 ++++++++++++++++++ extern/sdl4ogre/sdlinputwrapper.hpp | 67 +++ 14 files changed, 734 insertions(+), 409 deletions(-) delete mode 100644 apps/openmw/mwinput/sdlinputwrapper.cpp delete mode 100644 apps/openmw/mwinput/sdlinputwrapper.hpp create mode 100644 extern/sdl4ogre/CMakeLists.txt create mode 100644 extern/sdl4ogre/OISCompat.h rename extern/{oics/OISCompat.h => sdl4ogre/events.h} (53%) create mode 100644 extern/sdl4ogre/sdlinputwrapper.cpp create mode 100644 extern/sdl4ogre/sdlinputwrapper.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index de4be3895..37023571b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -474,6 +474,7 @@ endif(WIN32) # Extern add_subdirectory (extern/shiny) add_subdirectory (extern/oics) +add_subdirectory (extern/sdl4ogre) # Components add_subdirectory (components) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 4aa744e3b..faab842c3 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -20,7 +20,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - inputmanagerimp sdlinputwrapper + inputmanagerimp ) add_openmw_dir (mwgui @@ -108,6 +108,7 @@ target_link_libraries(openmw "shiny" "shiny.OgrePlatform" "oics" + "sdl4ogre" components ) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 763e75ae7..6d25f7dc6 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -62,13 +62,13 @@ namespace MWInput Ogre::RenderWindow* window = ogre.getWindow (); - mInputManager = new MWSDLInputWrapper(window); + mInputManager = new SFO::InputWrapper(window); mInputManager->setMouseEventCallback (this); mInputManager->setKeyboardEventCallback (this); mInputManager->setWindowEventCallback(this); std::string file = userFileExists ? userFile : ""; - mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); + mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last); adjustMouseRegion (window->getWidth(), window->getHeight()); @@ -78,7 +78,7 @@ namespace MWInput for (int i = 0; i < A_Last; ++i) { - mInputCtrl->getChannel (i)->addListener (this); + mInputBinder->getChannel (i)->addListener (this); } mControlSwitch["playercontrols"] = true; @@ -94,9 +94,9 @@ namespace MWInput InputManager::~InputManager() { - mInputCtrl->save (mUserFile); + mInputBinder->save (mUserFile); - delete mInputCtrl; + delete mInputBinder; delete mInputManager; } @@ -206,7 +206,7 @@ namespace MWInput // update values of channels (as a result of pressed keys) if (!loading) - mInputCtrl->update(dt); + mInputBinder->update(dt); // Update windows/gui as a result of input events // For instance this could mean opening a new window/dialog, @@ -396,12 +396,12 @@ namespace MWInput void InputManager::adjustMouseRegion(int width, int height) { - mInputCtrl->adjustMouseRegion(width, height); + mInputBinder->adjustMouseRegion(width, height); } bool InputManager::keyPressed( const SDL_KeyboardEvent &arg ) { - mInputCtrl->keyPressed (arg); + mInputBinder->keyPressed (arg); unsigned int text = arg.keysym.unicode; //TODO: Check if we need this with SDL @@ -414,23 +414,27 @@ namespace MWInput #endif */ - MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.keysym.sym), text); + OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); + + MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), text); return true; } bool InputManager::keyReleased(const SDL_KeyboardEvent &arg ) { - mInputCtrl->keyReleased (arg); + mInputBinder->keyReleased (arg); + + OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); - MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.keysym.sym)); + MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)); return true; } bool InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) { - mInputCtrl->mousePressed (arg, id); + mInputBinder->mousePressed (arg, id); MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)); @@ -448,16 +452,16 @@ namespace MWInput bool InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) { - mInputCtrl->mouseReleased (arg, id); + mInputBinder->mouseReleased (arg, id); MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)); return true; } - bool InputManager::mouseMoved( const ICS::MWSDLMouseMotionEvent &arg ) + bool InputManager::mouseMoved(const SFO::MouseMotionEvent &arg ) { - mInputCtrl->mouseMoved (arg); + mInputBinder->mouseMoved (arg); resetIdleTime (); @@ -683,7 +687,7 @@ namespace MWInput bool InputManager::actionIsActive (int id) { - return mInputCtrl->getChannel (id)->getValue () == 1; + return mInputBinder->getChannel (id)->getValue () == 1; } void InputManager::loadKeyDefaults (bool force) @@ -728,29 +732,29 @@ namespace MWInput for (int i = 0; i < A_Last; ++i) { ICS::Control* control; - bool controlExists = mInputCtrl->getChannel(i)->getControlsCount () != 0; + bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; if (!controlExists) { control = new ICS::Control(boost::lexical_cast(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX); - mInputCtrl->addControl(control); - control->attachChannel(mInputCtrl->getChannel(i), ICS::Channel::DIRECT); + mInputBinder->addControl(control); + control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); } else { - control = mInputCtrl->getChannel(i)->getAttachedControls ().front().control; + control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; } if (!controlExists || force || - ( mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) == SDLK_UNKNOWN - && mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS + ( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDLK_UNKNOWN + && mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) { clearAllBindings (control); if (defaultKeyBindings.find(i) != defaultKeyBindings.end()) - mInputCtrl->addKeyBinding(control, static_cast(defaultKeyBindings[i]), ICS::Control::INCREASE); + mInputBinder->addKeyBinding(control, static_cast(defaultKeyBindings[i]), ICS::Control::INCREASE); else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end()) - mInputCtrl->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); + mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); } } } @@ -794,15 +798,15 @@ namespace MWInput std::string InputManager::getActionBindingName (int action) { - if (mInputCtrl->getChannel (action)->getControlsCount () == 0) + if (mInputBinder->getChannel (action)->getControlsCount () == 0) return "#{sNone}"; - ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control; + ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - if (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE) != SDLK_UNKNOWN) - return mInputCtrl->keyCodeToString (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE)); - else if (mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - return "#{sMouse} " + boost::lexical_cast(mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE)); + if (mInputBinder->getKeyBinding (c, ICS::Control::INCREASE) != SDLK_UNKNOWN) + return mInputBinder->keyCodeToString (mInputBinder->getKeyBinding (c, ICS::Control::INCREASE)); + else if (mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) + return "#{sMouse} " + boost::lexical_cast(mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE)); else return "#{sNone}"; } @@ -842,9 +846,9 @@ namespace MWInput void InputManager::enableDetectingBindingMode (int action) { - ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control; + ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - mInputCtrl->enableDetectingBindingState (c, ICS::Control::INCREASE); + mInputBinder->enableDetectingBindingState (c, ICS::Control::INCREASE); } void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control @@ -905,10 +909,10 @@ namespace MWInput void InputManager::clearAllBindings (ICS::Control* control) { // right now we don't really need multiple bindings for the same action, so remove all others first - if (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) != SDLK_UNKNOWN) - mInputCtrl->removeKeyBinding (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE)); - if (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - mInputCtrl->removeMouseButtonBinding (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE)); + if (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) != SDLK_UNKNOWN) + mInputBinder->removeKeyBinding (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE)); + if (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) + mInputBinder->removeMouseButtonBinding (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE)); /// \todo add joysticks here once they are added } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 9a7656a67..34ea92a37 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -6,7 +6,7 @@ #include #include "../mwbase/inputmanager.hpp" -#include "sdlinputwrapper.hpp" +#include namespace OEngine { @@ -43,7 +43,6 @@ namespace MyGUI #include #include -#include namespace MWInput { @@ -53,9 +52,9 @@ namespace MWInput */ class InputManager : public MWBase::InputManager, - public ICS::MWSDLKeyListener, - public ICS::MWSDLMouseListener, - public ICS::MWSDLWindowListener, + public SFO::KeyListener, + public SFO::MouseListener, + public SFO::WindowListener, public ICS::ChannelListener, public ICS::DetectingBindingListener { @@ -93,7 +92,7 @@ namespace MWInput virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ); virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ); - virtual bool mouseMoved( const ICS::MWSDLMouseMotionEvent &arg ); + virtual bool mouseMoved( const SFO::MouseMotionEvent &arg ); virtual bool windowVisibilityChange( bool visible ); virtual bool windowFocusChange( bool have_focus ); @@ -129,10 +128,10 @@ namespace MWInput MWBase::WindowManager &mWindows; OMW::Engine& mEngine; - ICS::InputControlSystem* mInputCtrl; + ICS::InputControlSystem* mInputBinder; - MWSDLInputWrapper* mInputManager; + SFO::InputWrapper* mInputManager; std::string mUserFile; diff --git a/apps/openmw/mwinput/sdlinputwrapper.cpp b/apps/openmw/mwinput/sdlinputwrapper.cpp deleted file mode 100644 index 56b3568f5..000000000 --- a/apps/openmw/mwinput/sdlinputwrapper.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include "sdlinputwrapper.hpp" -#include -#include - -#include -#include - -#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX -# include -# include -# include -#endif - - -namespace MWInput -{ - MWSDLInputWrapper::MWSDLInputWrapper(Ogre::RenderWindow *window) : - mWindow(window), - mSDLWindow(NULL), - mWarpCompensate(false), - mMouseRelative(false), - mGrabPointer(false), - mWrapPointer(false) - { - _start(); - } - - MWSDLInputWrapper::~MWSDLInputWrapper() - { - if(mSDLWindow != NULL) - SDL_DestroyWindow(mSDLWindow); - mSDLWindow = NULL; - SDL_StopTextInput(); - SDL_Quit(); - } - - bool MWSDLInputWrapper::_start() - { - Uint32 flags = SDL_INIT_VIDEO; - if(SDL_WasInit(flags) == 0) - { - //get the HWND from ogre's renderwindow - size_t windowHnd; - mWindow->getCustomAttribute("WINDOW", &windowHnd); - - //kindly ask SDL not to trash our OGL context - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); - if(SDL_Init(SDL_INIT_VIDEO) != 0) - return false; - - //wrap our own event handler around ogre's - mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); - - if(mSDLWindow == NULL) - return false; - - SDL_StartTextInput(); - -#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX - //linux-specific event-handling fixups - SDL_SysWMinfo wm_info; - SDL_VERSION(&wm_info.version); - - if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info)) - { - Display* display = wm_info.info.x11.display; - Window w = wm_info.info.x11.window; - - // Set the input hints so we get keyboard input - XWMHints *wmhints = XAllocWMHints(); - if (wmhints) { - wmhints->input = True; - wmhints->flags = InputHint; - XSetWMHints(display, w, wmhints); - XFree(wmhints); - } - - //make sure to subscribe to XLib's events - XSelectInput(display, w, - (FocusChangeMask | EnterWindowMask | LeaveWindowMask | - ExposureMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | KeyPressMask | KeyReleaseMask | - PropertyChangeMask | StructureNotifyMask | - KeymapStateMask)); - - XFlush(display); - } -#endif - SDL_ShowCursor(SDL_FALSE); - } - - return true; - } - - void MWSDLInputWrapper::capture() - { - if(!_start()) - throw std::runtime_error(SDL_GetError()); - - SDL_Event evt; - while(SDL_PollEvent(&evt)) - { - switch(evt.type) - { - case SDL_MOUSEMOTION: - //ignore this if it happened due to a warp - if(!_handleWarpMotion(evt.motion)) - { - mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.motion)); - - //try to keep the mouse inside the window - _wrapMousePointer(evt.motion); - } - break; - case SDL_MOUSEWHEEL: - mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.wheel)); - break; - case SDL_MOUSEBUTTONDOWN: - mMouseListener->mousePressed(evt.button, evt.button.button); - break; - case SDL_MOUSEBUTTONUP: - mMouseListener->mouseReleased(evt.button, evt.button.button); - break; - - case SDL_KEYDOWN: - _handleKeyPress(evt.key); - break; - case SDL_KEYUP: - mKeyboardListener->keyReleased(evt.key); - break; - - case SDL_WINDOWEVENT_FOCUS_GAINED: - mWindowListener->windowFocusChange(true); - break; - case SDL_WINDOWEVENT_FOCUS_LOST: - mWindowListener->windowFocusChange(false); - break; - case SDL_WINDOWEVENT_EXPOSED: - mWindowListener->windowVisibilityChange(true); - break; - case SDL_WINDOWEVENT_HIDDEN: - mWindowListener->windowVisibilityChange(false); - break; - - //SDL traps ^C signals, pass it to OGRE. - case SDL_QUIT: - Ogre::Root::getSingleton().queueEndRendering(); - break; - } - } - } - - bool MWSDLInputWrapper::isModifierHeld(int mod) - { - return SDL_GetModState() & mod; - } - - void MWSDLInputWrapper::warpMouse(int x, int y) - { - SDL_WarpMouseInWindow(mSDLWindow, x, y); - mWarpCompensate = true; - mWarpX = x; - mWarpY = y; - } - - void MWSDLInputWrapper::setGrabPointer(bool grab) - { - SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE; - - mGrabPointer = grab; - SDL_SetWindowGrab(mSDLWindow, sdlGrab); - } - - void MWSDLInputWrapper::setMouseRelative(bool relative) - { - if(mMouseRelative == relative) - return; - - mMouseRelative = relative; - - mWrapPointer = false; - - //eep, wrap the pointer manually if the input driver doesn't support - //relative positioning natively - if(SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == -1) - { - if(relative) - mWrapPointer = true; - } - - //now remove all mouse events using the old setting from the queue - SDL_PumpEvents(); - - SDL_Event dummy[20]; - SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION); - } - - bool MWSDLInputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt) - { - if(!mWarpCompensate) - return false; - - //this was a warp event, signal the caller to eat it. - if(evt.x == mWarpX && evt.y == mWarpY) - { - mWarpCompensate = false; - return true; - } - - return false; - } - - void MWSDLInputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt) - { - //don't wrap if we don't want relative movements, support relative - //movements natively, or aren't grabbing anyways - if(!mMouseRelative || !mWrapPointer || !mGrabPointer) - return; - - int width = 0; - int height = 0; - - SDL_GetWindowSize(mSDLWindow, &width, &height); - - const int FUDGE_FACTOR_X = width / 4; - const int FUDGE_FACTOR_Y = height / 4; - - //warp the mouse if it's about to go outside the window - if(evt.x - FUDGE_FACTOR_X < 0 || evt.x + FUDGE_FACTOR_X > width - || evt.y - FUDGE_FACTOR_Y < 0 || evt.y + FUDGE_FACTOR_Y > height) - { - warpMouse(width / 2, height / 2); - } - } - - void MWSDLInputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt) - { - //SDL keyboard events are followed by the actual text those keys would generate - //to account for languages that require multiple keystrokes to produce a key. - //Look for an event immediately following ours, assuming each key produces exactly - //one character. - - //TODO: This won't work for multibyte characters, but MyGUI is the only consumer - //of these, does it even support multibyte characters? - - SDL_Event text_evts[1]; - if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0) - { - evt.keysym.unicode = text_evts[0].text.text[0]; - } - - mKeyboardListener->keyPressed(evt); - } -} diff --git a/apps/openmw/mwinput/sdlinputwrapper.hpp b/apps/openmw/mwinput/sdlinputwrapper.hpp deleted file mode 100644 index 6377d0bcf..000000000 --- a/apps/openmw/mwinput/sdlinputwrapper.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _MWINPUT_SDLINPUTWRAPPER_H -#define _MWINPUT_SDLINPUTWRAPPER_H - -#include "SDL2/SDL_events.h" -#include -#include - - -namespace MWInput -{ - class MWSDLInputWrapper - { - public: - MWSDLInputWrapper(Ogre::RenderWindow* window); - ~MWSDLInputWrapper(); - - void setMouseEventCallback(ICS::MWSDLMouseListener* listen) { mMouseListener = listen; } - void setKeyboardEventCallback(ICS::MWSDLKeyListener* listen) { mKeyboardListener = listen; } - void setWindowEventCallback(ICS::MWSDLWindowListener* listen) { mWindowListener = listen; } - - void capture(); - bool isModifierHeld(int mod); - - void setMouseRelative(bool relative); - bool getMouseRelative() { return mMouseRelative; } - void setGrabPointer(bool grab); - - void warpMouse(int x, int y); - private: - bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); - void _wrapMousePointer(const SDL_MouseMotionEvent &evt); - - void _handleKeyPress(SDL_KeyboardEvent& evt); - - bool _start(); - - ICS::MWSDLMouseListener* mMouseListener; - ICS::MWSDLKeyListener* mKeyboardListener; - ICS::MWSDLWindowListener* mWindowListener; - - Uint16 mWarpX; - Uint16 mWarpY; - bool mWarpCompensate; - bool mMouseRelative; - bool mWrapPointer; - bool mGrabPointer; - - Ogre::RenderWindow* mWindow; - SDL_Window* mSDLWindow; - }; -} - -#endif diff --git a/extern/oics/CMakeLists.txt b/extern/oics/CMakeLists.txt index 2e2a7a6d6..7c14387a4 100644 --- a/extern/oics/CMakeLists.txt +++ b/extern/oics/CMakeLists.txt @@ -9,7 +9,6 @@ set(OICS_SOURCE_FILES ICSInputControlSystem_keyboard.cpp ICSInputControlSystem_mouse.cpp ICSInputControlSystem_joystick.cpp - OISCompat.h tinyxml.cpp tinyxmlparser.cpp tinyxmlerror.cpp diff --git a/extern/oics/ICSInputControlSystem.h b/extern/oics/ICSInputControlSystem.h index 5d30b35cf..f42f9c0b5 100644 --- a/extern/oics/ICSInputControlSystem.h +++ b/extern/oics/ICSInputControlSystem.h @@ -32,7 +32,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "ICSControl.h" #include "ICSChannel.h" -#include "OISCompat.h" +#include "../sdl4ogre/events.h" #define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() ); #define ICS_MAX_JOYSTICK_AXIS 16 @@ -50,9 +50,9 @@ namespace ICS }; class DllExport InputControlSystem : - public MWSDLMouseListener, - public MWSDLKeyListener, - public MWSDLJoyStickListener + public SFO::MouseListener, + public SFO::KeyListener, + public SFO::JoyListener { public: @@ -102,7 +102,7 @@ namespace ICS JoystickIDList& getJoystickIdList(){ return mJoystickIDList; }; // MouseListener - bool mouseMoved(const MWSDLMouseMotionEvent &evt); + bool mouseMoved(const SFO::MouseMotionEvent &evt); bool mousePressed(const SDL_MouseButtonEvent &evt, Uint8); bool mouseReleased(const SDL_MouseButtonEvent &evt, Uint8); diff --git a/extern/oics/ICSInputControlSystem_mouse.cpp b/extern/oics/ICSInputControlSystem_mouse.cpp index 96197426a..52eb894ed 100644 --- a/extern/oics/ICSInputControlSystem_mouse.cpp +++ b/extern/oics/ICSInputControlSystem_mouse.cpp @@ -219,7 +219,7 @@ namespace ICS } // mouse Listeners - bool InputControlSystem::mouseMoved(const MWSDLMouseMotionEvent& evt) + bool InputControlSystem::mouseMoved(const SFO::MouseMotionEvent& evt) { if(mActive) { diff --git a/extern/sdl4ogre/CMakeLists.txt b/extern/sdl4ogre/CMakeLists.txt new file mode 100644 index 000000000..c52dd4cb4 --- /dev/null +++ b/extern/sdl4ogre/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SDL4OGRE_LIBRARY "sdl4ogre") + +# Sources + +set(SDL4OGRE_SOURCE_FILES + sdlinputwrapper.cpp +) + +add_library(${SDL4OGRE_LIBRARY} STATIC ${SDL4OGRE_SOURCE_FILES}) + +link_directories(${CMAKE_CURRENT_BINARY_DIR}) + + +target_link_libraries(${SDL4OGRE_LIBRARY} ${SDL2_LIBRARY}) diff --git a/extern/sdl4ogre/OISCompat.h b/extern/sdl4ogre/OISCompat.h new file mode 100644 index 000000000..04ba2c537 --- /dev/null +++ b/extern/sdl4ogre/OISCompat.h @@ -0,0 +1,159 @@ +#ifndef _OIS_SDL_COMPAT_H +#define _OIS_SDL_COMPAT_H + +#include +#include + +namespace OIS +{ +//! Keyboard scan codes +enum KeyCode +{ + KC_UNASSIGNED = 0x00, + KC_ESCAPE = 0x01, + KC_1 = 0x02, + KC_2 = 0x03, + KC_3 = 0x04, + KC_4 = 0x05, + KC_5 = 0x06, + KC_6 = 0x07, + KC_7 = 0x08, + KC_8 = 0x09, + KC_9 = 0x0A, + KC_0 = 0x0B, + KC_MINUS = 0x0C, // - on main keyboard + KC_EQUALS = 0x0D, + KC_BACK = 0x0E, // backspace + KC_TAB = 0x0F, + KC_Q = 0x10, + KC_W = 0x11, + KC_E = 0x12, + KC_R = 0x13, + KC_T = 0x14, + KC_Y = 0x15, + KC_U = 0x16, + KC_I = 0x17, + KC_O = 0x18, + KC_P = 0x19, + KC_LBRACKET = 0x1A, + KC_RBRACKET = 0x1B, + KC_RETURN = 0x1C, // Enter on main keyboard + KC_LCONTROL = 0x1D, + KC_A = 0x1E, + KC_S = 0x1F, + KC_D = 0x20, + KC_F = 0x21, + KC_G = 0x22, + KC_H = 0x23, + KC_J = 0x24, + KC_K = 0x25, + KC_L = 0x26, + KC_SEMICOLON = 0x27, + KC_APOSTROPHE = 0x28, + KC_GRAVE = 0x29, // accent + KC_LSHIFT = 0x2A, + KC_BACKSLASH = 0x2B, + KC_Z = 0x2C, + KC_X = 0x2D, + KC_C = 0x2E, + KC_V = 0x2F, + KC_B = 0x30, + KC_N = 0x31, + KC_M = 0x32, + KC_COMMA = 0x33, + KC_PERIOD = 0x34, // . on main keyboard + KC_SLASH = 0x35, // / on main keyboard + KC_RSHIFT = 0x36, + KC_MULTIPLY = 0x37, // * on numeric keypad + KC_LMENU = 0x38, // left Alt + KC_SPACE = 0x39, + KC_CAPITAL = 0x3A, + KC_F1 = 0x3B, + KC_F2 = 0x3C, + KC_F3 = 0x3D, + KC_F4 = 0x3E, + KC_F5 = 0x3F, + KC_F6 = 0x40, + KC_F7 = 0x41, + KC_F8 = 0x42, + KC_F9 = 0x43, + KC_F10 = 0x44, + KC_NUMLOCK = 0x45, + KC_SCROLL = 0x46, // Scroll Lock + KC_NUMPAD7 = 0x47, + KC_NUMPAD8 = 0x48, + KC_NUMPAD9 = 0x49, + KC_SUBTRACT = 0x4A, // - on numeric keypad + KC_NUMPAD4 = 0x4B, + KC_NUMPAD5 = 0x4C, + KC_NUMPAD6 = 0x4D, + KC_ADD = 0x4E, // + on numeric keypad + KC_NUMPAD1 = 0x4F, + KC_NUMPAD2 = 0x50, + KC_NUMPAD3 = 0x51, + KC_NUMPAD0 = 0x52, + KC_DECIMAL = 0x53, // . on numeric keypad + KC_OEM_102 = 0x56, // < > | on UK/Germany keyboards + KC_F11 = 0x57, + KC_F12 = 0x58, + KC_F13 = 0x64, // (NEC PC98) + KC_F14 = 0x65, // (NEC PC98) + KC_F15 = 0x66, // (NEC PC98) + KC_KANA = 0x70, // (Japanese keyboard) + KC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards + KC_CONVERT = 0x79, // (Japanese keyboard) + KC_NOCONVERT = 0x7B, // (Japanese keyboard) + KC_YEN = 0x7D, // (Japanese keyboard) + KC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards + KC_NUMPADEQUALS= 0x8D, // = on numeric keypad (NEC PC98) + KC_PREVTRACK = 0x90, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard) + KC_AT = 0x91, // (NEC PC98) + KC_COLON = 0x92, // (NEC PC98) + KC_UNDERLINE = 0x93, // (NEC PC98) + KC_KANJI = 0x94, // (Japanese keyboard) + KC_STOP = 0x95, // (NEC PC98) + KC_AX = 0x96, // (Japan AX) + KC_UNLABELED = 0x97, // (J3100) + KC_NEXTTRACK = 0x99, // Next Track + KC_NUMPADENTER = 0x9C, // Enter on numeric keypad + KC_RCONTROL = 0x9D, + KC_MUTE = 0xA0, // Mute + KC_CALCULATOR = 0xA1, // Calculator + KC_PLAYPAUSE = 0xA2, // Play / Pause + KC_MEDIASTOP = 0xA4, // Media Stop + KC_VOLUMEDOWN = 0xAE, // Volume - + KC_VOLUMEUP = 0xB0, // Volume + + KC_WEBHOME = 0xB2, // Web home + KC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98) + KC_DIVIDE = 0xB5, // / on numeric keypad + KC_SYSRQ = 0xB7, + KC_RMENU = 0xB8, // right Alt + KC_PAUSE = 0xC5, // Pause + KC_HOME = 0xC7, // Home on arrow keypad + KC_UP = 0xC8, // UpArrow on arrow keypad + KC_PGUP = 0xC9, // PgUp on arrow keypad + KC_LEFT = 0xCB, // LeftArrow on arrow keypad + KC_RIGHT = 0xCD, // RightArrow on arrow keypad + KC_END = 0xCF, // End on arrow keypad + KC_DOWN = 0xD0, // DownArrow on arrow keypad + KC_PGDOWN = 0xD1, // PgDn on arrow keypad + KC_INSERT = 0xD2, // Insert on arrow keypad + KC_DELETE = 0xD3, // Delete on arrow keypad + KC_LWIN = 0xDB, // Left Windows key + KC_RWIN = 0xDC, // Right Windows key + KC_APPS = 0xDD, // AppMenu key + KC_POWER = 0xDE, // System Power + KC_SLEEP = 0xDF, // System Sleep + KC_WAKE = 0xE3, // System Wake + KC_WEBSEARCH = 0xE5, // Web Search + KC_WEBFAVORITES= 0xE6, // Web Favorites + KC_WEBREFRESH = 0xE7, // Web Refresh + KC_WEBSTOP = 0xE8, // Web Stop + KC_WEBFORWARD = 0xE9, // Web Forward + KC_WEBBACK = 0xEA, // Web Back + KC_MYCOMPUTER = 0xEB, // My Computer + KC_MAIL = 0xEC, // Mail + KC_MEDIASELECT = 0xED // Media Select +}; +} +#endif diff --git a/extern/oics/OISCompat.h b/extern/sdl4ogre/events.h similarity index 53% rename from extern/oics/OISCompat.h rename to extern/sdl4ogre/events.h index 5813c17bf..945daf49a 100644 --- a/extern/oics/OISCompat.h +++ b/extern/sdl4ogre/events.h @@ -1,53 +1,20 @@ -#ifndef _OIS_SDL_COMPAT_H -#define _OIS_SDL_COMPAT_H +#ifndef _SFO_EVENTS_H +#define _SFO_EVENTS_H -#include -#include +#include -//TODO: Remove this. Right now we want to remain as close to OIS as possible -//So we can easily test the SDL backend //////////// // Events // //////////// -namespace ICS { +namespace SFO { /** Extended mouse event struct where we treat the wheel like an axis, like everyone expects */ -struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent { - - Sint16 zrel; - - MWSDLMouseMotionEvent() - { - _init(); - } - - MWSDLMouseMotionEvent( const SDL_MouseMotionEvent& evt) - { - _init(); - x = evt.x; - y = evt.y; - xrel = evt.xrel; - yrel = evt.yrel; - state = evt.state; - } - - MWSDLMouseMotionEvent (const SDL_MouseWheelEvent& evt) - { - _init(); - zrel = evt.y; - } - - void _init() - { - x = 0; - y = 0; - xrel = 0; - yrel = 0; - state = 0; - zrel = 0; - } +struct MouseMotionEvent : SDL_MouseMotionEvent { + + Sint32 zrel; + Sint32 z; }; @@ -55,27 +22,27 @@ struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent { // Listeners // /////////////// -class MWSDLMouseListener +class MouseListener { public: - virtual ~MWSDLMouseListener() {} - virtual bool mouseMoved( const MWSDLMouseMotionEvent &arg ) = 0; + virtual ~MouseListener() {} + virtual bool mouseMoved( const MouseMotionEvent &arg ) = 0; virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0; virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0; }; -class MWSDLKeyListener +class KeyListener { public: - virtual ~MWSDLKeyListener() {} + virtual ~KeyListener() {} virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0; virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0; }; -class MWSDLJoyStickListener +class JoyListener { public: - virtual ~MWSDLJoyStickListener() {} + virtual ~JoyListener() {} /** @remarks Joystick button down event */ virtual bool buttonPressed( const SDL_JoyButtonEvent &evt, int button ) = 0; @@ -91,10 +58,10 @@ public: virtual bool povMoved( const SDL_JoyHatEvent &arg, int index) {return true;} }; -class MWSDLWindowListener +class WindowListener { public: - virtual ~MWSDLWindowListener() {} + virtual ~WindowListener() {} /** @remarks The window's visibility changed */ virtual bool windowVisibilityChange( bool visible ) = 0; @@ -104,4 +71,5 @@ public: }; } + #endif diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp new file mode 100644 index 000000000..b7d1550c9 --- /dev/null +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -0,0 +1,420 @@ +#include "sdlinputwrapper.hpp" +#include + +#include +#include +#include + +#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX +# include +# include +# include +#endif + + +namespace SFO +{ + InputWrapper::InputWrapper(Ogre::RenderWindow *window) : + mWindow(window), + mSDLWindow(NULL), + mWarpCompensate(false), + mMouseRelative(false), + mGrabPointer(false), + mWrapPointer(false), + mMouseZ(0), + mMouseY(0), + mMouseX(0) + { + _start(); + _setupOISKeys(); + } + + InputWrapper::~InputWrapper() + { + if(mSDLWindow != NULL) + SDL_DestroyWindow(mSDLWindow); + mSDLWindow = NULL; + SDL_StopTextInput(); + SDL_Quit(); + } + + bool InputWrapper::_start() + { + Uint32 flags = SDL_INIT_VIDEO; + if(SDL_WasInit(flags) == 0) + { + //get the HWND from ogre's renderwindow + size_t windowHnd; + mWindow->getCustomAttribute("WINDOW", &windowHnd); + + //kindly ask SDL not to trash our OGL context + //might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ? + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); + if(SDL_Init(SDL_INIT_VIDEO) != 0) + return false; + + //wrap our own event handler around ogre's + mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); + + if(mSDLWindow == NULL) + return false; + + SDL_StartTextInput(); + +#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX + //linux-specific event-handling fixups + //see http://bugzilla.libsdl.org/show_bug.cgi?id=730 + SDL_SysWMinfo wm_info; + SDL_VERSION(&wm_info.version); + + if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info)) + { + Display* display = wm_info.info.x11.display; + Window w = wm_info.info.x11.window; + + // Set the input hints so we get keyboard input + XWMHints *wmhints = XAllocWMHints(); + if (wmhints) { + wmhints->input = True; + wmhints->flags = InputHint; + XSetWMHints(display, w, wmhints); + XFree(wmhints); + } + + //make sure to subscribe to XLib's events + XSelectInput(display, w, + (FocusChangeMask | EnterWindowMask | LeaveWindowMask | + ExposureMask | ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | KeyPressMask | KeyReleaseMask | + PropertyChangeMask | StructureNotifyMask | + KeymapStateMask)); + + XFlush(display); + } +#endif + SDL_ShowCursor(SDL_FALSE); + } + + return true; + } + + void InputWrapper::capture() + { + if(!_start()) + throw std::runtime_error(SDL_GetError()); + + SDL_Event evt; + while(SDL_PollEvent(&evt)) + { + switch(evt.type) + { + case SDL_MOUSEMOTION: + //ignore this if it happened due to a warp + if(!_handleWarpMotion(evt.motion)) + { + mMouseListener->mouseMoved(_packageMouseMotion(evt)); + + //try to keep the mouse inside the window + _wrapMousePointer(evt.motion); + } + break; + case SDL_MOUSEWHEEL: + mMouseListener->mouseMoved(_packageMouseMotion(evt)); + break; + case SDL_MOUSEBUTTONDOWN: + mMouseListener->mousePressed(evt.button, evt.button.button); + break; + case SDL_MOUSEBUTTONUP: + mMouseListener->mouseReleased(evt.button, evt.button.button); + break; + + case SDL_KEYDOWN: + _handleKeyPress(evt.key); + break; + case SDL_KEYUP: + mKeyboardListener->keyReleased(evt.key); + break; + + case SDL_WINDOWEVENT_FOCUS_GAINED: + mWindowListener->windowFocusChange(true); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + mWindowListener->windowFocusChange(false); + break; + case SDL_WINDOWEVENT_EXPOSED: + mWindowListener->windowVisibilityChange(true); + break; + case SDL_WINDOWEVENT_HIDDEN: + mWindowListener->windowVisibilityChange(false); + break; + + //SDL traps ^C signals, pass it to OGRE. + case SDL_QUIT: + Ogre::Root::getSingleton().queueEndRendering(); + break; + } + } + } + + bool InputWrapper::isModifierHeld(int mod) + { + return SDL_GetModState() & mod; + } + + void InputWrapper::warpMouse(int x, int y) + { + SDL_WarpMouseInWindow(mSDLWindow, x, y); + mWarpCompensate = true; + mWarpX = x; + mWarpY = y; + } + + void InputWrapper::setGrabPointer(bool grab) + { + SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE; + + mGrabPointer = grab; + SDL_SetWindowGrab(mSDLWindow, sdlGrab); + } + + void InputWrapper::setMouseRelative(bool relative) + { + if(mMouseRelative == relative) + return; + + mMouseRelative = relative; + + mWrapPointer = false; + + //eep, wrap the pointer manually if the input driver doesn't support + //relative positioning natively + if(SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == -1) + { + if(relative) + mWrapPointer = true; + } + + //now remove all mouse events using the old setting from the queue + SDL_PumpEvents(); + + SDL_Event dummy[20]; + SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION); + } + + bool InputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt) + { + if(!mWarpCompensate) + return false; + + //this was a warp event, signal the caller to eat it. + if(evt.x == mWarpX && evt.y == mWarpY) + { + mWarpCompensate = false; + return true; + } + + return false; + } + + void InputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt) + { + //don't wrap if we don't want relative movements, support relative + //movements natively, or aren't grabbing anyways + if(!mMouseRelative || !mWrapPointer || !mGrabPointer) + return; + + int width = 0; + int height = 0; + + SDL_GetWindowSize(mSDLWindow, &width, &height); + + const int FUDGE_FACTOR_X = width / 4; + const int FUDGE_FACTOR_Y = height / 4; + + //warp the mouse if it's about to go outside the window + if(evt.x - FUDGE_FACTOR_X < 0 || evt.x + FUDGE_FACTOR_X > width + || evt.y - FUDGE_FACTOR_Y < 0 || evt.y + FUDGE_FACTOR_Y > height) + { + warpMouse(width / 2, height / 2); + } + } + + void InputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt) + { + //SDL keyboard events are followed by the actual text those keys would generate + //to account for languages that require multiple keystrokes to produce a key. + //Look for an event immediately following ours, assuming each key produces exactly + //one character or none at all. + + //TODO: Check if this works properly for multibyte symbols + //do we have to worry about endian-ness? + //for that matter, check if we even need to do any of this. + + SDL_Event text_evts[1]; + if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0) + { + const char* symbol = text_evts[0].text.text; + + Uint32 num_bytes = strlen(symbol); + + //no valid character is more than 4 bytes + if(num_bytes > 0 && num_bytes <= 4) + { + Uint32 u32_symbol = boost::locale::conv::utf_to_utf(symbol)[0]; + + evt.keysym.unicode = u32_symbol; + } + } + + mKeyboardListener->keyPressed(evt); + } + + MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt) + { + MouseMotionEvent pack_evt; + pack_evt.x = mMouseX; + pack_evt.xrel = 0; + pack_evt.y = mMouseY; + pack_evt.yrel = 0; + pack_evt.z = mMouseZ; + pack_evt.zrel = 0; + + if(evt.type == SDL_MOUSEMOTION) + { + pack_evt.x = mMouseX = evt.motion.x; + pack_evt.y = mMouseY = evt.motion.y; + pack_evt.xrel = evt.motion.xrel; + pack_evt.yrel = evt.motion.yrel; + } + else if(evt.type == SDL_MOUSEWHEEL) + { + mMouseZ += pack_evt.zrel = evt.wheel.y; + pack_evt.z = mMouseZ; + } + else + { + throw new std::runtime_error("Tried to package non-motion event!"); + } + + return pack_evt; + } + + OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code) + { + OIS::KeyCode kc = OIS::KC_UNASSIGNED; + + KeyMap::const_iterator ois_equiv = mKeyMap.find(code); + + if(ois_equiv != mKeyMap.end()) + kc = ois_equiv->second; + + return kc; + } + + void InputWrapper::_setupOISKeys() + { + //lifted from OIS's SDLKeyboard.cpp + mKeyMap.insert( KeyMap::value_type(SDLK_UNKNOWN, OIS::KC_UNASSIGNED)); + mKeyMap.insert( KeyMap::value_type(SDLK_ESCAPE, OIS::KC_ESCAPE) ); + mKeyMap.insert( KeyMap::value_type(SDLK_1, OIS::KC_1) ); + mKeyMap.insert( KeyMap::value_type(SDLK_2, OIS::KC_2) ); + mKeyMap.insert( KeyMap::value_type(SDLK_3, OIS::KC_3) ); + mKeyMap.insert( KeyMap::value_type(SDLK_4, OIS::KC_4) ); + mKeyMap.insert( KeyMap::value_type(SDLK_5, OIS::KC_5) ); + mKeyMap.insert( KeyMap::value_type(SDLK_6, OIS::KC_6) ); + mKeyMap.insert( KeyMap::value_type(SDLK_7, OIS::KC_7) ); + mKeyMap.insert( KeyMap::value_type(SDLK_8, OIS::KC_8) ); + mKeyMap.insert( KeyMap::value_type(SDLK_9, OIS::KC_9) ); + mKeyMap.insert( KeyMap::value_type(SDLK_0, OIS::KC_0) ); + mKeyMap.insert( KeyMap::value_type(SDLK_MINUS, OIS::KC_MINUS) ); + mKeyMap.insert( KeyMap::value_type(SDLK_EQUALS, OIS::KC_EQUALS) ); + mKeyMap.insert( KeyMap::value_type(SDLK_BACKSPACE, OIS::KC_BACK) ); + mKeyMap.insert( KeyMap::value_type(SDLK_TAB, OIS::KC_TAB) ); + mKeyMap.insert( KeyMap::value_type(SDLK_q, OIS::KC_Q) ); + mKeyMap.insert( KeyMap::value_type(SDLK_w, OIS::KC_W) ); + mKeyMap.insert( KeyMap::value_type(SDLK_e, OIS::KC_E) ); + mKeyMap.insert( KeyMap::value_type(SDLK_r, OIS::KC_R) ); + mKeyMap.insert( KeyMap::value_type(SDLK_t, OIS::KC_T) ); + mKeyMap.insert( KeyMap::value_type(SDLK_y, OIS::KC_Y) ); + mKeyMap.insert( KeyMap::value_type(SDLK_u, OIS::KC_U) ); + mKeyMap.insert( KeyMap::value_type(SDLK_i, OIS::KC_I) ); + mKeyMap.insert( KeyMap::value_type(SDLK_o, OIS::KC_O) ); + mKeyMap.insert( KeyMap::value_type(SDLK_p, OIS::KC_P) ); + mKeyMap.insert( KeyMap::value_type(SDLK_RETURN, OIS::KC_RETURN) ); + mKeyMap.insert( KeyMap::value_type(SDLK_LCTRL, OIS::KC_LCONTROL)); + mKeyMap.insert( KeyMap::value_type(SDLK_a, OIS::KC_A) ); + mKeyMap.insert( KeyMap::value_type(SDLK_s, OIS::KC_S) ); + mKeyMap.insert( KeyMap::value_type(SDLK_d, OIS::KC_D) ); + mKeyMap.insert( KeyMap::value_type(SDLK_f, OIS::KC_F) ); + mKeyMap.insert( KeyMap::value_type(SDLK_g, OIS::KC_G) ); + mKeyMap.insert( KeyMap::value_type(SDLK_h, OIS::KC_H) ); + mKeyMap.insert( KeyMap::value_type(SDLK_j, OIS::KC_J) ); + mKeyMap.insert( KeyMap::value_type(SDLK_k, OIS::KC_K) ); + mKeyMap.insert( KeyMap::value_type(SDLK_l, OIS::KC_L) ); + mKeyMap.insert( KeyMap::value_type(SDLK_SEMICOLON, OIS::KC_SEMICOLON) ); + mKeyMap.insert( KeyMap::value_type(SDLK_COLON, OIS::KC_COLON) ); + mKeyMap.insert( KeyMap::value_type(SDLK_QUOTE, OIS::KC_APOSTROPHE) ); + mKeyMap.insert( KeyMap::value_type(SDLK_BACKQUOTE, OIS::KC_GRAVE) ); + mKeyMap.insert( KeyMap::value_type(SDLK_LSHIFT, OIS::KC_LSHIFT) ); + mKeyMap.insert( KeyMap::value_type(SDLK_BACKSLASH, OIS::KC_BACKSLASH) ); + mKeyMap.insert( KeyMap::value_type(SDLK_SLASH, OIS::KC_SLASH) ); + mKeyMap.insert( KeyMap::value_type(SDLK_z, OIS::KC_Z) ); + mKeyMap.insert( KeyMap::value_type(SDLK_x, OIS::KC_X) ); + mKeyMap.insert( KeyMap::value_type(SDLK_c, OIS::KC_C) ); + mKeyMap.insert( KeyMap::value_type(SDLK_v, OIS::KC_V) ); + mKeyMap.insert( KeyMap::value_type(SDLK_b, OIS::KC_B) ); + mKeyMap.insert( KeyMap::value_type(SDLK_n, OIS::KC_N) ); + mKeyMap.insert( KeyMap::value_type(SDLK_m, OIS::KC_M) ); + mKeyMap.insert( KeyMap::value_type(SDLK_COMMA, OIS::KC_COMMA) ); + mKeyMap.insert( KeyMap::value_type(SDLK_PERIOD, OIS::KC_PERIOD)); + mKeyMap.insert( KeyMap::value_type(SDLK_RSHIFT, OIS::KC_RSHIFT)); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_MULTIPLY, OIS::KC_MULTIPLY) ); + mKeyMap.insert( KeyMap::value_type(SDLK_LALT, OIS::KC_LMENU) ); + mKeyMap.insert( KeyMap::value_type(SDLK_SPACE, OIS::KC_SPACE)); + mKeyMap.insert( KeyMap::value_type(SDLK_CAPSLOCK, OIS::KC_CAPITAL) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F1, OIS::KC_F1) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F2, OIS::KC_F2) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F3, OIS::KC_F3) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F4, OIS::KC_F4) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F5, OIS::KC_F5) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F6, OIS::KC_F6) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F7, OIS::KC_F7) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F8, OIS::KC_F8) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F9, OIS::KC_F9) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F10, OIS::KC_F10) ); + mKeyMap.insert( KeyMap::value_type(SDLK_NUMLOCKCLEAR, OIS::KC_NUMLOCK) ); + mKeyMap.insert( KeyMap::value_type(SDLK_SCROLLLOCK, OIS::KC_SCROLL)); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_7, OIS::KC_NUMPAD7) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_8, OIS::KC_NUMPAD8) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_9, OIS::KC_NUMPAD9) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_MINUS, OIS::KC_SUBTRACT) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_4, OIS::KC_NUMPAD4) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_5, OIS::KC_NUMPAD5) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_6, OIS::KC_NUMPAD6) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_PLUS, OIS::KC_ADD) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_1, OIS::KC_NUMPAD1) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_2, OIS::KC_NUMPAD2) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_3, OIS::KC_NUMPAD3) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_0, OIS::KC_NUMPAD0) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_PERIOD, OIS::KC_DECIMAL) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F11, OIS::KC_F11) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F12, OIS::KC_F12) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F13, OIS::KC_F13) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F14, OIS::KC_F14) ); + mKeyMap.insert( KeyMap::value_type(SDLK_F15, OIS::KC_F15) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_EQUALS, OIS::KC_NUMPADEQUALS) ); + mKeyMap.insert( KeyMap::value_type(SDLK_KP_DIVIDE, OIS::KC_DIVIDE) ); + mKeyMap.insert( KeyMap::value_type(SDLK_SYSREQ, OIS::KC_SYSRQ) ); + mKeyMap.insert( KeyMap::value_type(SDLK_RALT, OIS::KC_RMENU) ); + mKeyMap.insert( KeyMap::value_type(SDLK_HOME, OIS::KC_HOME) ); + mKeyMap.insert( KeyMap::value_type(SDLK_UP, OIS::KC_UP) ); + mKeyMap.insert( KeyMap::value_type(SDLK_PAGEUP, OIS::KC_PGUP) ); + mKeyMap.insert( KeyMap::value_type(SDLK_LEFT, OIS::KC_LEFT) ); + mKeyMap.insert( KeyMap::value_type(SDLK_RIGHT, OIS::KC_RIGHT) ); + mKeyMap.insert( KeyMap::value_type(SDLK_END, OIS::KC_END) ); + mKeyMap.insert( KeyMap::value_type(SDLK_DOWN, OIS::KC_DOWN) ); + mKeyMap.insert( KeyMap::value_type(SDLK_PAGEDOWN, OIS::KC_PGDOWN) ); + mKeyMap.insert( KeyMap::value_type(SDLK_INSERT, OIS::KC_INSERT) ); + mKeyMap.insert( KeyMap::value_type(SDLK_DELETE, OIS::KC_DELETE) ); + } +} diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp new file mode 100644 index 000000000..63b4c922b --- /dev/null +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -0,0 +1,67 @@ +#ifndef _MWINPUT_SDLINPUTWRAPPER_H +#define _MWINPUT_SDLINPUTWRAPPER_H + +#include "SDL2/SDL_events.h" +#include +#include + +#include "OISCompat.h" +#include "events.h" + + +namespace SFO +{ + class InputWrapper + { + public: + InputWrapper(Ogre::RenderWindow* window); + ~InputWrapper(); + + void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; } + void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; } + void setWindowEventCallback(WindowListener* listen) { mWindowListener = listen; } + + void capture(); + bool isModifierHeld(int mod); + + void setMouseRelative(bool relative); + bool getMouseRelative() { return mMouseRelative; } + void setGrabPointer(bool grab); + + OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code); + + void warpMouse(int x, int y); + private: + bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); + void _wrapMousePointer(const SDL_MouseMotionEvent &evt); + + MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); + void _handleKeyPress(SDL_KeyboardEvent& evt); + + bool _start(); + void _setupOISKeys(); + + SFO::MouseListener* mMouseListener; + SFO::KeyListener* mKeyboardListener; + SFO::WindowListener* mWindowListener; + + typedef boost::unordered::unordered_map KeyMap; + KeyMap mKeyMap; + + Uint16 mWarpX; + Uint16 mWarpY; + bool mWarpCompensate; + bool mMouseRelative; + bool mWrapPointer; + bool mGrabPointer; + + Sint32 mMouseZ; + Sint32 mMouseX; + Sint32 mMouseY; + + Ogre::RenderWindow* mWindow; + SDL_Window* mSDLWindow; + }; +} + +#endif From 601d79ef3f83d741d1913911845863037000690b Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Thu, 10 Jan 2013 17:59:49 -0400 Subject: [PATCH 010/213] fix the mouse wheel in mygui --- apps/openmw/mwinput/inputmanagerimp.cpp | 3 +-- extern/sdl4ogre/sdlinputwrapper.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 6d25f7dc6..308065e7e 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -487,8 +487,7 @@ namespace MWInput mMouseX = std::max(0.f, std::min(mMouseX, float(viewSize.width))); mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height))); - //there's no such thing as an absolute z position, so let's keep track of it ourselves - mMouseWheel += arg.zrel; + mMouseWheel = int(arg.z); MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel); } diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index b7d1550c9..93f00d4b5 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -288,7 +288,7 @@ namespace SFO } else if(evt.type == SDL_MOUSEWHEEL) { - mMouseZ += pack_evt.zrel = evt.wheel.y; + mMouseZ += pack_evt.zrel = (evt.wheel.y * 120); pack_evt.z = mMouseZ; } else From 403b6756f516cb700c2f033890947070b29892c9 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Thu, 10 Jan 2013 23:29:51 -0400 Subject: [PATCH 011/213] remove dependency on boost::locale, use system mouse position in in-game menus --- apps/openmw/mwinput/inputmanagerimp.cpp | 21 ++--- extern/sdl4ogre/sdlinputwrapper.cpp | 101 +++++++++++++++++------- extern/sdl4ogre/sdlinputwrapper.hpp | 7 +- 3 files changed, 84 insertions(+), 45 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 308065e7e..358eb7b92 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -221,9 +221,10 @@ namespace MWInput bool main_menu = mWindows.containsMode(MWGui::GM_MainMenu); bool was_relative = mInputManager->getMouseRelative(); - bool is_relative = !main_menu; + bool is_relative = !mWindows.isGuiMode(); - //don't keep the pointer away from the window edge in the main menu + // don't keep the pointer away from the window edge in gui mode + // stop using raw mouse motions and switch to system cursor movements mInputManager->setMouseRelative(is_relative); //we switched to non-relative mode, move our cursor to where the in-game @@ -472,17 +473,11 @@ namespace MWInput // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor - //FIXME: Except in the main menu, since we let the pointer escape - if(!mWindows.containsMode(MWGui::GM_MainMenu)) - { - mMouseX += float(arg.xrel) * mUISensitivity; - mMouseY += float(arg.yrel) * mUISensitivity * mUIYMultiplier; - } - else - { - mMouseX = arg.x; - mMouseY = arg.y; - } + // Don't support the UI sensitivity slider to reduce headache + // related to when the mouse can leave the window, and what to + // do when it re-enters + mMouseX = arg.x; + mMouseY = arg.y; mMouseX = std::max(0.f, std::min(mMouseX, float(viewSize.width))); mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height))); diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 93f00d4b5..a198542c7 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -3,7 +3,6 @@ #include #include -#include #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX # include @@ -239,6 +238,36 @@ namespace SFO } } + MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt) + { + MouseMotionEvent pack_evt; + pack_evt.x = mMouseX; + pack_evt.xrel = 0; + pack_evt.y = mMouseY; + pack_evt.yrel = 0; + pack_evt.z = mMouseZ; + pack_evt.zrel = 0; + + if(evt.type == SDL_MOUSEMOTION) + { + pack_evt.x = mMouseX = evt.motion.x; + pack_evt.y = mMouseY = evt.motion.y; + pack_evt.xrel = evt.motion.xrel; + pack_evt.yrel = evt.motion.yrel; + } + else if(evt.type == SDL_MOUSEWHEEL) + { + mMouseZ += pack_evt.zrel = (evt.wheel.y * 120); + pack_evt.z = mMouseZ; + } + else + { + throw new std::runtime_error("Tried to package non-motion event!"); + } + + return pack_evt; + } + void InputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt) { //SDL keyboard events are followed by the actual text those keys would generate @@ -253,50 +282,58 @@ namespace SFO SDL_Event text_evts[1]; if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0) { - const char* symbol = text_evts[0].text.text; - - Uint32 num_bytes = strlen(symbol); - - //no valid character is more than 4 bytes - if(num_bytes > 0 && num_bytes <= 4) + if(strlen(text_evts[0].text.text) != 0) { - Uint32 u32_symbol = boost::locale::conv::utf_to_utf(symbol)[0]; - - evt.keysym.unicode = u32_symbol; + const unsigned char* symbol = reinterpret_cast(&(text_evts[0].text.text[0])); + evt.keysym.unicode = _UTF8ToUTF32(symbol); } } mKeyboardListener->keyPressed(evt); } - MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt) + //Lifted from OIS' LinuxKeyboard.cpp + Uint32 InputWrapper::_UTF8ToUTF32(const unsigned char *buf) { - MouseMotionEvent pack_evt; - pack_evt.x = mMouseX; - pack_evt.xrel = 0; - pack_evt.y = mMouseY; - pack_evt.yrel = 0; - pack_evt.z = mMouseZ; - pack_evt.zrel = 0; + unsigned char FirstChar = buf[0]; - if(evt.type == SDL_MOUSEMOTION) + //it's an ascii char, bail out early. + if(FirstChar < 128) + return FirstChar; + + Uint32 val = 0; + Sint32 len = 0; + + if((FirstChar & 0xE0) == 0xC0) //2 Chars { - pack_evt.x = mMouseX = evt.motion.x; - pack_evt.y = mMouseY = evt.motion.y; - pack_evt.xrel = evt.motion.xrel; - pack_evt.yrel = evt.motion.yrel; + len = 2; + val = FirstChar & 0x1F; } - else if(evt.type == SDL_MOUSEWHEEL) + else if((FirstChar & 0xF0) == 0xE0) //3 Chars { - mMouseZ += pack_evt.zrel = (evt.wheel.y * 120); - pack_evt.z = mMouseZ; + len = 3; + val = FirstChar & 0x0F; } - else + else if((FirstChar & 0xF8) == 0xF0) //4 Chars { - throw new std::runtime_error("Tried to package non-motion event!"); + len = 4; + val = FirstChar & 0x07; + } + else if((FirstChar & 0xFC) == 0xF8) //5 Chars + { + len = 5; + val = FirstChar & 0x03; + } + else // if((FirstChar & 0xFE) == 0xFC) //6 Chars + { + len = 6; + val = FirstChar & 0x01; } - return pack_evt; + for(int i = 1; i < len; i++) + val = (val << 6) | (buf[i] & 0x3F); + + return val; } OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code) @@ -307,6 +344,8 @@ namespace SFO if(ois_equiv != mKeyMap.end()) kc = ois_equiv->second; + else + std::cerr << "Couldn't find OIS key for " << SDLK_SYSREQ << std::endl; return kc; } @@ -314,6 +353,10 @@ namespace SFO void InputWrapper::_setupOISKeys() { //lifted from OIS's SDLKeyboard.cpp + + //TODO: Consider switching to scancodes so we + //can properly support international keyboards + //look at SDL_GetKeyFromScancode and SDL_GetKeyName mKeyMap.insert( KeyMap::value_type(SDLK_UNKNOWN, OIS::KC_UNASSIGNED)); mKeyMap.insert( KeyMap::value_type(SDLK_ESCAPE, OIS::KC_ESCAPE) ); mKeyMap.insert( KeyMap::value_type(SDLK_1, OIS::KC_1) ); diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index 63b4c922b..55c45316f 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -32,13 +32,14 @@ namespace SFO void warpMouse(int x, int y); private: + bool _start(); + bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); void _wrapMousePointer(const SDL_MouseMotionEvent &evt); - MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); - void _handleKeyPress(SDL_KeyboardEvent& evt); - bool _start(); + void _handleKeyPress(SDL_KeyboardEvent& evt); + Uint32 _UTF8ToUTF32(const unsigned char *buf); void _setupOISKeys(); SFO::MouseListener* mMouseListener; From a030c035133d4fcbad08272bb33997adfd45580c Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Thu, 10 Jan 2013 23:53:19 -0400 Subject: [PATCH 012/213] support the printscreen button properly --- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- extern/oics/ICSInputControlSystem.cpp | 1 + extern/sdl4ogre/sdlinputwrapper.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 358eb7b92..7785167f8 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -716,7 +716,7 @@ namespace MWInput defaultKeyBindings[A_QuickKey8] = SDLK_8; defaultKeyBindings[A_QuickKey9] = SDLK_9; defaultKeyBindings[A_QuickKey10] = SDLK_0; - defaultKeyBindings[A_Screenshot] = SDLK_SYSREQ; + defaultKeyBindings[A_Screenshot] = SDLK_PRINTSCREEN; defaultKeyBindings[A_ToggleHUD] = SDLK_F12; std::map defaultMouseButtonBindings; diff --git a/extern/oics/ICSInputControlSystem.cpp b/extern/oics/ICSInputControlSystem.cpp index 159b3241f..cdf8fbfe2 100644 --- a/extern/oics/ICSInputControlSystem.cpp +++ b/extern/oics/ICSInputControlSystem.cpp @@ -892,6 +892,7 @@ namespace ICS mKeys["RCONTROL"]= SDLK_RCTRL; mKeys["DIVIDE"]= SDLK_SLASH; mKeys["SYSRQ"]= SDLK_SYSREQ; + mKeys["PRNTSCRN"] = SDLK_PRINTSCREEN; mKeys["RMENU"]= SDLK_RALT; mKeys["PAUSE"]= SDLK_PAUSE; mKeys["HOME"]= SDLK_HOME; diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index a198542c7..e194719cb 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -345,7 +345,7 @@ namespace SFO if(ois_equiv != mKeyMap.end()) kc = ois_equiv->second; else - std::cerr << "Couldn't find OIS key for " << SDLK_SYSREQ << std::endl; + std::cerr << "Couldn't find OIS key for " << code << std::endl; return kc; } From 1117105039768175d517a758f216ad1cb0d8c992 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Fri, 11 Jan 2013 00:37:04 -0400 Subject: [PATCH 013/213] fix compile error with boost includes --- extern/sdl4ogre/sdlinputwrapper.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index 55c45316f..eba2ed8d0 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -46,7 +46,7 @@ namespace SFO SFO::KeyListener* mKeyboardListener; SFO::WindowListener* mWindowListener; - typedef boost::unordered::unordered_map KeyMap; + typedef boost::unordered_map KeyMap; KeyMap mKeyMap; Uint16 mWarpX; From f9b064d1bc17699558b2298eb35ed271cf43b8e6 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Fri, 11 Jan 2013 08:27:59 -0400 Subject: [PATCH 014/213] add preliminary hardware cursor support into sdl4ogre and windowmanagerimp, handle alt-tabbing away from fullscreen gracefully --- apps/openmw/mwbase/windowmanager.hpp | 7 ++ apps/openmw/mwgui/cursorreplace.cpp | 64 +++++++++++ apps/openmw/mwgui/cursorreplace.hpp | 35 +++++++ apps/openmw/mwgui/windowmanagerimp.cpp | 51 +++++++++ apps/openmw/mwgui/windowmanagerimp.hpp | 11 ++ apps/openmw/mwinput/inputmanagerimp.cpp | 2 + extern/sdl4ogre/sdlinputwrapper.cpp | 134 +++++++++++++++++++++++- extern/sdl4ogre/sdlinputwrapper.hpp | 35 ++++++- 8 files changed, 334 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 13a35b592..e7a63a1b5 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -55,6 +55,11 @@ namespace MWGui class DialogueWindow; } +namespace SFO +{ + class CursorChangeClient; +} + namespace MWBase { /// \brief Interface for widnow manager (implemented in MWGui) @@ -238,6 +243,8 @@ namespace MWBase virtual void startTraining(MWWorld::Ptr actor) = 0; virtual const Translation::Storage& getTranslationDataStorage() const = 0; + + virtual void setCursorChangeClient(SFO::CursorChangeClient* client) = 0; }; } diff --git a/apps/openmw/mwgui/cursorreplace.cpp b/apps/openmw/mwgui/cursorreplace.cpp index 2079538fc..f883a4ed7 100644 --- a/apps/openmw/mwgui/cursorreplace.cpp +++ b/apps/openmw/mwgui/cursorreplace.cpp @@ -5,9 +5,73 @@ #include #include +#include using namespace MWGui; + +#include "MyGUI_Precompiled.h" +#include "MyGUI_ResourceImageSetPointer.h" +#include "MyGUI_ImageBox.h" +#include "MyGUI_ResourceManager.h" + + + + ResourceImageSetPointerFix::ResourceImageSetPointerFix() : + mImageSet(nullptr) + { + } + + ResourceImageSetPointerFix::~ResourceImageSetPointerFix() + { + } + + void ResourceImageSetPointerFix::deserialization(xml::ElementPtr _node, Version _version) + { + Base::deserialization(_node, _version); + + // берем детей и крутимся, основной цикл + xml::ElementEnumerator info = _node->getElementEnumerator(); + while (info.next("Property")) + { + const std::string& key = info->findAttribute("key"); + const std::string& value = info->findAttribute("value"); + + if (key == "Point") + mPoint = IntPoint::parse(value); + else if (key == "Size") + mSize = IntSize::parse(value); + else if (key == "Resource") + mImageSet = ResourceManager::getInstance().getByName(value)->castType(); + } + } + + void ResourceImageSetPointerFix::setImage(ImageBox* _image) + { + if (mImageSet != nullptr) + _image->setItemResourceInfo(mImageSet->getIndexInfo(0, 0)); + } + + void ResourceImageSetPointerFix::setPosition(ImageBox* _image, const IntPoint& _point) + { + _image->setCoord(_point.left - mPoint.left, _point.top - mPoint.top, mSize.width, mSize.height); + } + + ResourceImageSetPtr ResourceImageSetPointerFix:: getImageSet() + { + return mImageSet; + } + + IntPoint ResourceImageSetPointerFix::getHotSpot() + { + return mPoint; + } + + IntSize ResourceImageSetPointerFix::getSize() + { + return mSize; + } + CursorReplace::CursorReplace() { OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90); diff --git a/apps/openmw/mwgui/cursorreplace.hpp b/apps/openmw/mwgui/cursorreplace.hpp index 06fe28e39..402eda1ab 100644 --- a/apps/openmw/mwgui/cursorreplace.hpp +++ b/apps/openmw/mwgui/cursorreplace.hpp @@ -2,9 +2,44 @@ #define GAME_CURSORREPLACE_H #include +#include +#include + +using namespace MyGUI; namespace MWGui { + /// \brief A simple class that allows us to get the members of + /// ResourceImageSetPointer that we need. Use with + /// MyGUI + /// \example MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); + /// MyGUI::ResourceManager::getInstance().load("core.xml"); + class ResourceImageSetPointerFix : + public IPointer + { + MYGUI_RTTI_DERIVED( ResourceImageSetPointerFix ) + + public: + ResourceImageSetPointerFix(); + virtual ~ResourceImageSetPointerFix(); + + virtual void deserialization(xml::ElementPtr _node, Version _version); + + virtual void setImage(ImageBox* _image); + virtual void setPosition(ImageBox* _image, const IntPoint& _point); + + //and now for the whole point of this class, allow us to get + //the hot spot, the image and the size of the cursor. + virtual ResourceImageSetPtr getImageSet(); + virtual IntPoint getHotSpot(); + virtual IntSize getSize(); + + private: + IntPoint mPoint; + IntSize mSize; + ResourceImageSetPtr mImageSet; + }; + /// \brief MyGUI does not support rotating cursors, so we have to do it manually class CursorReplace { diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index d653b578a..7c99d004e 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -4,10 +4,15 @@ #include #include "MyGUI_UString.h" +#include "MYGUI/MyGUI_IPointer.h" +#include "MYGUI/MyGUI_ResourceImageSetPointer.h" +#include "MyGUI_TextureUtility.h" #include #include +#include + #include #include @@ -53,6 +58,8 @@ #include "trainingwindow.hpp" #include "imagebutton.hpp" +#include "cursorreplace.hpp" + using namespace MWGui; WindowManager::WindowManager( @@ -108,12 +115,17 @@ WindowManager::WindowManager( , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) , mHudEnabled(true) , mTranslationDataStorage (translationDataStorage) + , mCursorChangeClient(NULL) { // Set up the GUI system mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath); mGui = mGuiManager->getGui(); + //Use our own ResourceImageSetPointer class so we can get the texture and hotspot for a pointer + MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); + MyGUI::ResourceManager::getInstance().load("core.xml"); + //Register own widgets with MyGUI MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); @@ -130,6 +142,7 @@ WindowManager::WindowManager( MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag); + MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange); // Get size info from the Gui object assert(mGui); @@ -758,6 +771,44 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r } } + void WindowManager::setCursorChangeClient(SFO::CursorChangeClient* client) + { + mCursorChangeClient = client; + onCursorChange(PointerManager::getInstance().getDefaultPointer()); + } + +void WindowManager::onCursorChange(const std::string &name) +{ + //we have no client, don't care. + if(!mCursorChangeClient) + return; + + //the client doesn't want any more info about this cursor + if(!mCursorChangeClient->cursorChanged(name)) + return; + //See if we can get the information we need out of the cursor resource + ResourceImageSetPointerFix* imgSetPtr = dynamic_cast(MyGUI::PointerManager::getInstance().getByName(name)); + if(imgSetPtr != NULL) + { + MyGUI::ResourceImageSet* imgSet = imgSetPtr->getImageSet(); + + std::string tex_name = imgSet->getIndexInfo(0,0).texture; + + Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().getByName(tex_name); + + //everything looks good, send it to the client + if(!tex.isNull()) + { + Uint8 size_x = imgSetPtr->getSize().width; + Uint8 size_y = imgSetPtr->getSize().height; + Uint8 hotspot_x = imgSetPtr->getHotSpot().left; + Uint8 hotspot_y = imgSetPtr->getHotSpot().top; + + mCursorChangeClient->receiveCursorInfo(name, tex, size_x, size_y, hotspot_x, hotspot_y); + } + } +} + void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed) { mHud->setFpsLevel(Settings::Manager::getInt("fps", "HUD")); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index e2a966660..bbcdbbb41 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -48,6 +48,11 @@ namespace OEngine } } +namespace SFO +{ + class CursorChangeClient; +} + namespace MWGui { class WindowBase; @@ -228,6 +233,8 @@ namespace MWGui virtual const Translation::Storage& getTranslationDataStorage() const; + virtual void setCursorChangeClient(SFO::CursorChangeClient* client); + private: OEngine::GUI::MyGUIManager *mGuiManager; HUD *mHud; @@ -282,6 +289,8 @@ namespace MWGui MyGUI::Gui *mGui; // Gui std::vector mGuiModes; + SFO::CursorChangeClient* mCursorChangeClient; + std::vector mGarbageDialogs; void cleanupGarbage(); @@ -310,6 +319,8 @@ namespace MWGui * so this method will retrieve the GMST with the name \a _tag and place the result in \a _result */ void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result); + + void onCursorChange(const std::string& name); }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 7785167f8..c1f857b5f 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -67,6 +67,8 @@ namespace MWInput mInputManager->setKeyboardEventCallback (this); mInputManager->setWindowEventCallback(this); + mWindows.setCursorChangeClient(mInputManager); + std::string file = userFileExists ? userFile : ""; mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last); diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index e194719cb..1b996ce06 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX # include @@ -13,6 +15,8 @@ namespace SFO { + /// \brief General purpose wrapper for OGRE applications around SDL's event + /// queue, mostly used for handling input-related events. InputWrapper::InputWrapper(Ogre::RenderWindow *window) : mWindow(window), mSDLWindow(NULL), @@ -58,6 +62,11 @@ namespace SFO if(mSDLWindow == NULL) return false; + //without this SDL will take ownership of the window and iconify it when + //we alt-tab away. + SDL_SetWindowFullscreen(mSDLWindow, 0); + + //translate our keypresses into text SDL_StartTextInput(); #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX @@ -160,6 +169,7 @@ namespace SFO return SDL_GetModState() & mod; } + /// \brief Moves the mouse to the specified point within the viewport void InputWrapper::warpMouse(int x, int y) { SDL_WarpMouseInWindow(mSDLWindow, x, y); @@ -168,14 +178,15 @@ namespace SFO mWarpY = y; } + /// \brief Locks the pointer to the window void InputWrapper::setGrabPointer(bool grab) { - SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE; - mGrabPointer = grab; - SDL_SetWindowGrab(mSDLWindow, sdlGrab); + SDL_SetWindowGrab(mSDLWindow, grab ? SDL_TRUE : SDL_FALSE); } + /// \brief Set the mouse to relative positioning. Doesn't move the cursor + /// and disables mouse acceleration. void InputWrapper::setMouseRelative(bool relative) { if(mMouseRelative == relative) @@ -200,6 +211,121 @@ namespace SFO SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION); } + bool InputWrapper::cursorChanged(const std::string &name) + { + CursorMap::const_iterator curs_iter = mCursorMap.find(name); + + //we have this cursor + if(curs_iter != mCursorMap.end()) + { + SDL_SetCursor(curs_iter->second); + return false; + } + else + { + //they should get back to use with more info + return true; + } + } + + void InputWrapper::receiveCursorInfo(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) + { + _createCursorFromResource(name, tex, size_x, size_y, hotspot_x, hotspot_y); + } + + /// \brief creates an SDL cursor from an Ogre texture + void InputWrapper::_createCursorFromResource(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) + { + Ogre::Image::Box box; + box.right = size_x; + box.bottom = size_y; + + //get the surfaces set up + Ogre::HardwarePixelBufferSharedPtr buffer = tex.get()->getBuffer(); + buffer.get()->lock(box, Ogre::HardwarePixelBuffer::HBL_READ_ONLY); + + std::string tempName = "_" + name + "_processing"; + + //we need to copy this to a temporary texture since Ogre doesn't like us using getColourAt + Ogre::TexturePtr tempTexture = Ogre::TextureManager::getSingleton().createManual( + tempName, + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, + size_x, size_y, + 0, + Ogre::PF_FLOAT16_RGBA, + Ogre::TU_STATIC); + + tempTexture->getBuffer()->blit(buffer); + buffer->unlock(); + + Ogre::HardwarePixelBufferSharedPtr new_buffer = tempTexture.get()->getBuffer(); + //FIXME: Casting away constness is almost certainly the wrong thing to do here + Ogre::PixelBox& pixels = const_cast(new_buffer->lock(box, Ogre::HardwarePixelBuffer::HBL_READ_ONLY)); + + + SDL_Surface* surf = SDL_CreateRGBSurface(0,size_x,size_y,32,0,0,0,0); + + + //copy the Ogre texture to an SDL surface + for(size_t x = 0; x < size_x; ++x) + { + for(size_t y = 0; y < size_y; ++y) + { + Ogre::ColourValue clr = pixels.getColourAt(x, y, 0); + + //set the pixel on the SDL surface to the same value as the Ogre texture's + _putPixel(surf, x, y, SDL_MapRGBA(surf->format, clr.r, clr.g, clr.b, clr.a)); + } + } + + //set the cursor and store it for later + SDL_Cursor* curs = SDL_CreateColorCursor(surf, hotspot_x, hotspot_y); + SDL_SetCursor(curs); + mCursorMap.insert(CursorMap::value_type(std::string(name), curs)); + + new_buffer->unlock(); + + //clean up + SDL_FreeSurface(surf); + Ogre::TextureManager::getSingleton().remove(tempName); + } + + void InputWrapper::_putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) + { + int bpp = surface->format->BytesPerPixel; + /* Here p is the address to the pixel we want to set */ + Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; + + switch(bpp) { + case 1: + *p = pixel; + break; + + case 2: + *(Uint16 *)p = pixel; + break; + + case 3: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { + p[0] = (pixel >> 16) & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = pixel & 0xff; + } else { + p[0] = pixel & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = (pixel >> 16) & 0xff; + } + break; + + case 4: + *(Uint32 *)p = pixel; + break; + } + } + + /// \brief Internal method for ignoring relative motions as a side effect + /// of warpMouse() bool InputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt) { if(!mWarpCompensate) @@ -215,6 +341,7 @@ namespace SFO return false; } + /// \brief Wrap the mouse to the viewport void InputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt) { //don't wrap if we don't want relative movements, support relative @@ -238,6 +365,7 @@ namespace SFO } } + /// \brief Package mouse and mousewheel motions into a single event MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt) { MouseMotionEvent pack_evt; diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index eba2ed8d0..aac2bf566 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -9,13 +9,33 @@ #include "events.h" +namespace Ogre +{ + class Texture; +} + namespace SFO { - class InputWrapper + + + class CursorChangeClient + { + public: + /// \brief Tell the client that the cursor has changed, giving the + /// name of the cursor we changed to ("arrow", "ibeam", etc) + /// \return Whether the client is interested in more information about the cursor + virtual bool cursorChanged(const std::string &name) = 0; + + /// \brief Follow up a cursorChanged() call with enough info to create an SDL cursor. + virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0; + }; + + class InputWrapper : + public CursorChangeClient { public: InputWrapper(Ogre::RenderWindow* window); - ~InputWrapper(); + virtual ~InputWrapper(); void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; } void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; } @@ -28,9 +48,13 @@ namespace SFO bool getMouseRelative() { return mMouseRelative; } void setGrabPointer(bool grab); + virtual bool cursorChanged(const std::string &name); + virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); + OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code); void warpMouse(int x, int y); + private: bool _start(); @@ -38,6 +62,9 @@ namespace SFO void _wrapMousePointer(const SDL_MouseMotionEvent &evt); MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); + void _createCursorFromResource(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); + void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); + void _handleKeyPress(SDL_KeyboardEvent& evt); Uint32 _UTF8ToUTF32(const unsigned char *buf); void _setupOISKeys(); @@ -49,6 +76,9 @@ namespace SFO typedef boost::unordered_map KeyMap; KeyMap mKeyMap; + typedef std::map CursorMap; + CursorMap mCursorMap; + Uint16 mWarpX; Uint16 mWarpY; bool mWarpCompensate; @@ -63,6 +93,7 @@ namespace SFO Ogre::RenderWindow* mWindow; SDL_Window* mSDLWindow; }; + } #endif From eeacb04fe24e4d21f91c407e839c662a8f41a83d Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Fri, 11 Jan 2013 09:32:29 -0400 Subject: [PATCH 015/213] Fully working hardware cursors (if you compile SDL2 with XCursor support) --- apps/openmw/mwbase/windowmanager.hpp | 2 +- apps/openmw/mwgui/windowmanagerimp.cpp | 22 ++++++++++++++++------ apps/openmw/mwgui/windowmanagerimp.hpp | 3 ++- extern/sdl4ogre/sdlinputwrapper.cpp | 9 +++++++-- extern/sdl4ogre/sdlinputwrapper.hpp | 4 ++++ 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index e7a63a1b5..c7dc06472 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -159,7 +159,7 @@ namespace MWBase virtual void setFocusObject(const MWWorld::Ptr& focus) = 0; virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) = 0; - virtual void setMouseVisible(bool visible) = 0; + virtual void setCursorVisible(bool visible) = 0; virtual void getMousePosition(int &x, int &y) = 0; virtual void getMousePosition(float &x, float &y) = 0; virtual void setDragDrop(bool dragDrop) = 0; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 7c99d004e..781f3c86c 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -190,6 +190,9 @@ WindowManager::WindowManager( mInputBlocker = mGui->createWidget("",0,0,w,h,MyGUI::Align::Default,"Windows",""); + //make sure the cursor in the GL context isn't visible + MyGUI::PointerManager::getInstance().setVisible(false); + // The HUD is always on mHud->setVisible(true); @@ -302,7 +305,7 @@ void WindowManager::updateVisible() mHud->setVisible(true); // Mouse is visible whenever we're not in game mode - MyGUI::PointerManager::getInstance().setVisible(isGuiMode()); + setCursorVisible(isGuiMode()); bool gameMode = !isGuiMode(); @@ -417,13 +420,13 @@ void WindowManager::updateVisible() break; case GM_LoadingWallpaper: mHud->setVisible(false); - MyGUI::PointerManager::getInstance().setVisible(false); + setCursorVisible(false); break; case GM_Loading: - MyGUI::PointerManager::getInstance().setVisible(false); + setCursorVisible(false); break; case GM_Video: - MyGUI::PointerManager::getInstance().setVisible(false); + setCursorVisible(false); mHud->setVisible(false); break; default: @@ -737,9 +740,15 @@ void WindowManager::setSpellVisibility(bool visible) mHud->setEffectVisible (visible); } -void WindowManager::setMouseVisible(bool visible) +void WindowManager::setCursorVisible(bool visible) { - MyGUI::PointerManager::getInstance().setVisible(visible); + if(visible == mCursorVisible) + return; + + mCursorVisible = visible; + + if(mCursorChangeClient != NULL) + mCursorChangeClient->cursorVisible(visible); } void WindowManager::setDragDrop(bool dragDrop) @@ -775,6 +784,7 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r { mCursorChangeClient = client; onCursorChange(PointerManager::getInstance().getDefaultPointer()); + client->cursorVisible(mCursorVisible); } void WindowManager::onCursorChange(const std::string &name) diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index bbcdbbb41..4334de83f 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -154,7 +154,7 @@ namespace MWGui virtual void setFocusObject(const MWWorld::Ptr& focus); virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y); - virtual void setMouseVisible(bool visible); + virtual void setCursorVisible(bool visible); virtual void getMousePosition(int &x, int &y); virtual void getMousePosition(float &x, float &y); virtual void setDragDrop(bool dragDrop); @@ -275,6 +275,7 @@ namespace MWGui bool mCrosshairEnabled; bool mSubtitlesEnabled; bool mHudEnabled; + bool mCursorVisible; /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed. // Various stats about player as needed by window manager diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 1b996ce06..c996924e4 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -228,6 +228,11 @@ namespace SFO } } + void InputWrapper::cursorVisible(bool visible) + { + SDL_ShowCursor(visible ? SDL_TRUE : SDL_FALSE); + } + void InputWrapper::receiveCursorInfo(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) { _createCursorFromResource(name, tex, size_x, size_y, hotspot_x, hotspot_y); @@ -264,7 +269,7 @@ namespace SFO Ogre::PixelBox& pixels = const_cast(new_buffer->lock(box, Ogre::HardwarePixelBuffer::HBL_READ_ONLY)); - SDL_Surface* surf = SDL_CreateRGBSurface(0,size_x,size_y,32,0,0,0,0); + SDL_Surface* surf = SDL_CreateRGBSurface(0,size_x,size_y,32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF); //copy the Ogre texture to an SDL surface @@ -275,7 +280,7 @@ namespace SFO Ogre::ColourValue clr = pixels.getColourAt(x, y, 0); //set the pixel on the SDL surface to the same value as the Ogre texture's - _putPixel(surf, x, y, SDL_MapRGBA(surf->format, clr.r, clr.g, clr.b, clr.a)); + _putPixel(surf, x, y, SDL_MapRGBA(surf->format, clr.r*255, clr.g*255, clr.b*255, clr.a*255)); } } diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index aac2bf566..d37a43e33 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -28,6 +28,9 @@ namespace SFO /// \brief Follow up a cursorChanged() call with enough info to create an SDL cursor. virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0; + + /// \brief Tell the client when the cursor visibility changed + virtual void cursorVisible(bool visible) = 0; }; class InputWrapper : @@ -50,6 +53,7 @@ namespace SFO virtual bool cursorChanged(const std::string &name); virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); + virtual void cursorVisible(bool visible); OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code); From 651a654985a50820bed817f4374cbbc83a842afa Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Fri, 11 Jan 2013 10:09:26 -0400 Subject: [PATCH 016/213] clean up our cursors during destruction --- extern/sdl4ogre/sdlinputwrapper.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index c996924e4..190612fd8 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -37,6 +37,17 @@ namespace SFO if(mSDLWindow != NULL) SDL_DestroyWindow(mSDLWindow); mSDLWindow = NULL; + + CursorMap::const_iterator curs_iter = mCursorMap.begin(); + + while(curs_iter != mCursorMap.end()) + { + SDL_FreeCursor(curs_iter->second); + ++curs_iter; + } + + mCursorMap.clear(); + SDL_StopTextInput(); SDL_Quit(); } From d71b58385536589e58b16bb8d2f8d3c1cac6a9cb Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 11 Jan 2013 22:25:34 +0100 Subject: [PATCH 017/213] fix const cast, fix comment --- extern/sdl4ogre/sdlinputwrapper.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 190612fd8..b6761e883 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -252,17 +252,14 @@ namespace SFO /// \brief creates an SDL cursor from an Ogre texture void InputWrapper::_createCursorFromResource(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) { - Ogre::Image::Box box; - box.right = size_x; - box.bottom = size_y; - //get the surfaces set up Ogre::HardwarePixelBufferSharedPtr buffer = tex.get()->getBuffer(); - buffer.get()->lock(box, Ogre::HardwarePixelBuffer::HBL_READ_ONLY); + buffer.get()->lock(Ogre::HardwarePixelBuffer::HBL_READ_ONLY); std::string tempName = "_" + name + "_processing"; - //we need to copy this to a temporary texture since Ogre doesn't like us using getColourAt + //we need to copy this to a temporary texture first because the cursors might be in DDS format, + //and Ogre doesn't have an interface to read DDS Ogre::TexturePtr tempTexture = Ogre::TextureManager::getSingleton().createManual( tempName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, @@ -275,10 +272,9 @@ namespace SFO tempTexture->getBuffer()->blit(buffer); buffer->unlock(); - Ogre::HardwarePixelBufferSharedPtr new_buffer = tempTexture.get()->getBuffer(); - //FIXME: Casting away constness is almost certainly the wrong thing to do here - Ogre::PixelBox& pixels = const_cast(new_buffer->lock(box, Ogre::HardwarePixelBuffer::HBL_READ_ONLY)); - + // now blit to memory + Ogre::Image destImage; + tempTexture->convertToImage(destImage); SDL_Surface* surf = SDL_CreateRGBSurface(0,size_x,size_y,32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF); @@ -288,7 +284,7 @@ namespace SFO { for(size_t y = 0; y < size_y; ++y) { - Ogre::ColourValue clr = pixels.getColourAt(x, y, 0); + Ogre::ColourValue clr = destImage.getColourAt(x, y, 0); //set the pixel on the SDL surface to the same value as the Ogre texture's _putPixel(surf, x, y, SDL_MapRGBA(surf->format, clr.r*255, clr.g*255, clr.b*255, clr.a*255)); @@ -300,8 +296,6 @@ namespace SFO SDL_SetCursor(curs); mCursorMap.insert(CursorMap::value_type(std::string(name), curs)); - new_buffer->unlock(); - //clean up SDL_FreeSurface(surf); Ogre::TextureManager::getSingleton().remove(tempName); From 5a6589af0155b058fc63c095f38c8568c59f6c77 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Sat, 12 Jan 2013 11:57:29 -0400 Subject: [PATCH 018/213] extract cursor management to a separate class, have windowmanager communicate with it. Initialize SDL during engine start --- apps/openmw/engine.cpp | 15 ++ apps/openmw/mwbase/windowmanager.hpp | 4 +- apps/openmw/mwgui/windowmanagerimp.cpp | 57 +++--- apps/openmw/mwgui/windowmanagerimp.hpp | 9 +- apps/openmw/mwinput/inputmanagerimp.cpp | 9 +- extern/sdl4ogre/CMakeLists.txt | 8 +- extern/sdl4ogre/cursormanager.hpp | 35 ++++ extern/sdl4ogre/sdlcursormanager.cpp | 189 ++++++++++++++++++++ extern/sdl4ogre/sdlcursormanager.hpp | 44 +++++ extern/sdl4ogre/sdlinputwrapper.cpp | 222 +++++------------------- extern/sdl4ogre/sdlinputwrapper.hpp | 41 +---- 11 files changed, 383 insertions(+), 250 deletions(-) create mode 100644 extern/sdl4ogre/cursormanager.hpp create mode 100644 extern/sdl4ogre/sdlcursormanager.cpp create mode 100644 extern/sdl4ogre/sdlcursormanager.hpp diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 4413e98f4..51dbabba5 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -36,6 +36,8 @@ #include "mwmechanics/mechanicsmanagerimp.hpp" +#include "SDL2/SDL.h" + void OMW::Engine::executeLocalScripts() { @@ -272,6 +274,9 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings) else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg")) nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); + settings.setBool("hardware cursors", "GUI", true); + settings.setBool("debug", "Engine", mDebug); + return settingspath; } @@ -322,6 +327,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) loadBSA(); + Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE; + if(SDL_WasInit(flags) == 0) + { + //kindly ask SDL not to trash our OGL context + //might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ? + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); + if(SDL_Init(flags) != 0) + throw std::runtime_error("Couldn't initialize SDL!"); + } + // cursor replacer (converts the cursor from the bsa so they can be used by mygui) MWGui::CursorReplace replacer; diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index c7dc06472..06b1df7b9 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -57,7 +57,7 @@ namespace MWGui namespace SFO { - class CursorChangeClient; + class CursorManager; } namespace MWBase @@ -243,8 +243,6 @@ namespace MWBase virtual void startTraining(MWWorld::Ptr actor) = 0; virtual const Translation::Storage& getTranslationDataStorage() const = 0; - - virtual void setCursorChangeClient(SFO::CursorChangeClient* client) = 0; }; } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 781f3c86c..20301b1b2 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -115,7 +115,8 @@ WindowManager::WindowManager( , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) , mHudEnabled(true) , mTranslationDataStorage (translationDataStorage) - , mCursorChangeClient(NULL) + , mCursorManager(NULL) + , mUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI")) { // Set up the GUI system @@ -190,9 +191,6 @@ WindowManager::WindowManager( mInputBlocker = mGui->createWidget("",0,0,w,h,MyGUI::Align::Default,"Windows",""); - //make sure the cursor in the GL context isn't visible - MyGUI::PointerManager::getInstance().setVisible(false); - // The HUD is always on mHud->setVisible(true); @@ -212,6 +210,13 @@ WindowManager::WindowManager( unsetSelectedSpell(); unsetSelectedWeapon(); + //set up the hardware cursor manager + mCursorManager = new SFO::SDLCursorManager(Settings::Manager::getBool("debug", "Engine")); + + setUseHardwareCursors(mUseHardwareCursors); + onCursorChange(PointerManager::getInstance().getDefaultPointer()); + mCursorManager->cursorVisibilityChange(false); + // Set up visibility updateVisible(); } @@ -252,6 +257,7 @@ WindowManager::~WindowManager() cleanupGarbage(); delete mGuiManager; + delete mCursorManager; } void WindowManager::cleanupGarbage() @@ -740,15 +746,30 @@ void WindowManager::setSpellVisibility(bool visible) mHud->setEffectVisible (visible); } +void WindowManager::setUseHardwareCursors(bool use) +{ + mCursorManager->setEnabled(use); + + if(!use) + { + MyGUI::PointerManager::getInstance().setVisible(false); + } + else + { + MyGUI::PointerManager::getInstance().setVisible(mCursorVisible); + } +} + void WindowManager::setCursorVisible(bool visible) { - if(visible == mCursorVisible) + if(mCursorVisible == visible) return; mCursorVisible = visible; + mCursorManager->cursorVisibilityChange(visible); - if(mCursorChangeClient != NULL) - mCursorChangeClient->cursorVisible(visible); + if(!mUseHardwareCursors) + MyGUI::PointerManager::getInstance().setVisible(visible); } void WindowManager::setDragDrop(bool dragDrop) @@ -780,21 +801,10 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r } } - void WindowManager::setCursorChangeClient(SFO::CursorChangeClient* client) - { - mCursorChangeClient = client; - onCursorChange(PointerManager::getInstance().getDefaultPointer()); - client->cursorVisible(mCursorVisible); - } - void WindowManager::onCursorChange(const std::string &name) { - //we have no client, don't care. - if(!mCursorChangeClient) - return; - - //the client doesn't want any more info about this cursor - if(!mCursorChangeClient->cursorChanged(name)) + //the cursor manager doesn't want any more info about this cursor + if(!mCursorManager->cursorChanged(name)) return; //See if we can get the information we need out of the cursor resource ResourceImageSetPointerFix* imgSetPtr = dynamic_cast(MyGUI::PointerManager::getInstance().getByName(name)); @@ -806,7 +816,7 @@ void WindowManager::onCursorChange(const std::string &name) Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().getByName(tex_name); - //everything looks good, send it to the client + //everything looks good, send it to the cursor manager if(!tex.isNull()) { Uint8 size_x = imgSetPtr->getSize().width; @@ -814,7 +824,7 @@ void WindowManager::onCursorChange(const std::string &name) Uint8 hotspot_x = imgSetPtr->getHotSpot().left; Uint8 hotspot_y = imgSetPtr->getHotSpot().top; - mCursorChangeClient->receiveCursorInfo(name, tex, size_x, size_y, hotspot_x, hotspot_y); + mCursorManager->receiveCursorInfo(name, tex, size_x, size_y, hotspot_x, hotspot_y); } } } @@ -823,6 +833,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector { mHud->setFpsLevel(Settings::Manager::getInt("fps", "HUD")); mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI")); + setUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI")); bool changeRes = false; for (Settings::CategorySettingVector::const_iterator it = changed.begin(); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 4334de83f..874de8af9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -50,7 +50,7 @@ namespace OEngine namespace SFO { - class CursorChangeClient; + class CursorManager; } namespace MWGui @@ -233,8 +233,6 @@ namespace MWGui virtual const Translation::Storage& getTranslationDataStorage() const; - virtual void setCursorChangeClient(SFO::CursorChangeClient* client); - private: OEngine::GUI::MyGUIManager *mGuiManager; HUD *mHud; @@ -290,7 +288,7 @@ namespace MWGui MyGUI::Gui *mGui; // Gui std::vector mGuiModes; - SFO::CursorChangeClient* mCursorChangeClient; + SFO::CursorManager* mCursorManager; std::vector mGarbageDialogs; void cleanupGarbage(); @@ -315,6 +313,9 @@ namespace MWGui void onDialogueWindowBye(); + bool mUseHardwareCursors; + void setUseHardwareCursors(bool use); + /** * Called when MyGUI tries to retrieve a tag. This usually corresponds to a GMST string, * so this method will retrieve the GMST with the name \a _tag and place the result in \a _result diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index c1f857b5f..9d80de91e 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -67,8 +68,6 @@ namespace MWInput mInputManager->setKeyboardEventCallback (this); mInputManager->setWindowEventCallback(this); - mWindows.setCursorChangeClient(mInputManager); - std::string file = userFileExists ? userFile : ""; mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last); @@ -225,6 +224,9 @@ namespace MWInput bool was_relative = mInputManager->getMouseRelative(); bool is_relative = !mWindows.isGuiMode(); + //we let the mouse escape in the main menu + mInputManager->setGrabPointer(!main_menu); + // don't keep the pointer away from the window edge in gui mode // stop using raw mouse motions and switch to system cursor movements mInputManager->setMouseRelative(is_relative); @@ -235,9 +237,6 @@ namespace MWInput { mInputManager->warpMouse(mMouseX, mMouseY); } - - //we let the mouse escape in the main menu - mInputManager->setGrabPointer(!main_menu); } // Disable movement in Gui mode diff --git a/extern/sdl4ogre/CMakeLists.txt b/extern/sdl4ogre/CMakeLists.txt index c52dd4cb4..493d1ce47 100644 --- a/extern/sdl4ogre/CMakeLists.txt +++ b/extern/sdl4ogre/CMakeLists.txt @@ -4,9 +4,15 @@ set(SDL4OGRE_LIBRARY "sdl4ogre") set(SDL4OGRE_SOURCE_FILES sdlinputwrapper.cpp + sdlcursormanager.cpp ) -add_library(${SDL4OGRE_LIBRARY} STATIC ${SDL4OGRE_SOURCE_FILES}) +set(SDL4OGRE_HEADER_FILES + OISCompat.h + cursormanager.hpp +) + +add_library(${SDL4OGRE_LIBRARY} STATIC ${SDL4OGRE_SOURCE_FILES} ${SDL4OGRE_HEADER_FILES}) link_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/extern/sdl4ogre/cursormanager.hpp b/extern/sdl4ogre/cursormanager.hpp new file mode 100644 index 000000000..938f5f4c2 --- /dev/null +++ b/extern/sdl4ogre/cursormanager.hpp @@ -0,0 +1,35 @@ +#ifndef _SDL4OGRE_CURSOR_MANAGER_H +#define _SDL4OGRE_CURSOR_MANAGER_H + +#include "SDL2/SDL_types.h" +#include + +namespace Ogre +{ + class TexturePtr; +} + +namespace SFO +{ +class CursorManager +{ +public: + virtual ~CursorManager(){} + + /// \brief Tell the manager that the cursor has changed, giving the + /// name of the cursor we changed to ("arrow", "ibeam", etc) + /// \return Whether the manager is interested in more information about the cursor + virtual bool cursorChanged(const std::string &name) = 0; + + /// \brief Follow up a cursorChanged() call with enough info to create an cursor. + virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0; + + /// \brief Tell the manager when the cursor visibility changed + virtual void cursorVisibilityChange(bool visible) = 0; + + /// \brief sets whether to actively manage cursors or not + virtual void setEnabled(bool enabled) = 0; +}; +} + +#endif diff --git a/extern/sdl4ogre/sdlcursormanager.cpp b/extern/sdl4ogre/sdlcursormanager.cpp new file mode 100644 index 000000000..4e24696ea --- /dev/null +++ b/extern/sdl4ogre/sdlcursormanager.cpp @@ -0,0 +1,189 @@ +#include "sdlcursormanager.hpp" + +#include +#include + +namespace SFO +{ + + SDLCursorManager::SDLCursorManager(bool debug) : + mDebug(debug), + mEnabled(false), + mCursorVisible(false), + mInitialized(false) + { + } + + SDLCursorManager::~SDLCursorManager() + { + CursorMap::const_iterator curs_iter = mCursorMap.begin(); + + while(curs_iter != mCursorMap.end()) + { + SDL_FreeCursor(curs_iter->second); + ++curs_iter; + } + + mCursorMap.clear(); + } + + void SDLCursorManager::setEnabled(bool enabled) + { + if(mInitialized && enabled == mEnabled) + return; + + mInitialized = true; + mEnabled = enabled; + + //turn on hardware cursors + if(enabled) + { + _setGUICursor(mCurrentCursor); + } + //turn off hardware cursors + else + { + if(!mDebug) + SDL_ShowCursor(SDL_FALSE); + } + } + + bool SDLCursorManager::cursorChanged(const std::string &name) + { + mCurrentCursor = name; + + CursorMap::const_iterator curs_iter = mCursorMap.find(name); + + //we have this cursor + if(curs_iter != mCursorMap.end()) + { + _setGUICursor(name); + + return false; + } + else + { + //they should get back to us with more info + return true; + } + } + + void SDLCursorManager::_setGUICursor(const std::string &name) + { + if(mEnabled && (mDebug || mCursorVisible)) + { + SDL_SetCursor(mCursorMap.find(name)->second); + _setCursorVisible(mCursorVisible); + } + } + + void SDLCursorManager::_setCursorVisible(bool visible) + { + if(!mEnabled) + return; + + if(mDebug) + visible = true; + + SDL_ShowCursor(visible ? SDL_TRUE : SDL_FALSE); + } + + void SDLCursorManager::cursorVisibilityChange(bool visible) + { + mCursorVisible = visible; + + _setGUICursor(mCurrentCursor); + _setCursorVisible(visible); + } + + void SDLCursorManager::receiveCursorInfo(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) + { + _createCursorFromResource(name, tex, size_x, size_y, hotspot_x, hotspot_y); + } + + /// \brief creates an SDL cursor from an Ogre texture + void SDLCursorManager::_createCursorFromResource(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) + { + //get the surfaces set up + Ogre::HardwarePixelBufferSharedPtr buffer = tex.get()->getBuffer(); + buffer.get()->lock(Ogre::HardwarePixelBuffer::HBL_READ_ONLY); + + std::string tempName = "_" + name + "_processing"; + + //we need to copy this to a temporary texture first because the cursors might be in DDS format, + //and Ogre doesn't have an interface to read DDS + Ogre::TexturePtr tempTexture = Ogre::TextureManager::getSingleton().createManual( + tempName, + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, + size_x, size_y, + 0, + Ogre::PF_FLOAT16_RGBA, + Ogre::TU_STATIC); + + tempTexture->getBuffer()->blit(buffer); + buffer->unlock(); + + // now blit to memory + Ogre::Image destImage; + tempTexture->convertToImage(destImage); + + SDL_Surface* surf = SDL_CreateRGBSurface(0,size_x,size_y,32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF); + + + //copy the Ogre texture to an SDL surface + for(size_t x = 0; x < size_x; ++x) + { + for(size_t y = 0; y < size_y; ++y) + { + Ogre::ColourValue clr = destImage.getColourAt(x, y, 0); + + //set the pixel on the SDL surface to the same value as the Ogre texture's + _putPixel(surf, x, y, SDL_MapRGBA(surf->format, clr.r*255, clr.g*255, clr.b*255, clr.a*255)); + } + } + + //set the cursor and store it for later + SDL_Cursor* curs = SDL_CreateColorCursor(surf, hotspot_x, hotspot_y); + mCursorMap.insert(CursorMap::value_type(std::string(name), curs)); + + //clean up + SDL_FreeSurface(surf); + Ogre::TextureManager::getSingleton().remove(tempName); + + _setGUICursor(name); + } + + void SDLCursorManager::_putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) + { + int bpp = surface->format->BytesPerPixel; + /* Here p is the address to the pixel we want to set */ + Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; + + switch(bpp) { + case 1: + *p = pixel; + break; + + case 2: + *(Uint16 *)p = pixel; + break; + + case 3: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { + p[0] = (pixel >> 16) & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = pixel & 0xff; + } else { + p[0] = pixel & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = (pixel >> 16) & 0xff; + } + break; + + case 4: + *(Uint32 *)p = pixel; + break; + } + } +} diff --git a/extern/sdl4ogre/sdlcursormanager.hpp b/extern/sdl4ogre/sdlcursormanager.hpp new file mode 100644 index 000000000..2de192377 --- /dev/null +++ b/extern/sdl4ogre/sdlcursormanager.hpp @@ -0,0 +1,44 @@ +#ifndef _SDL4OGRE_CURSORMANAGER_H +#define _SDL4OGRE_CURSORMANAGER_H + +#include "SDL.h" + +#include "cursormanager.hpp" +#include + +namespace SFO +{ + class SDLCursorManager : + public CursorManager + { + public: + SDLCursorManager(bool debug=false); + virtual ~SDLCursorManager(); + + virtual void setEnabled(bool enabled); + + virtual bool cursorChanged(const std::string &name); + virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); + virtual void cursorVisibilityChange(bool visible); + + private: + void _createCursorFromResource(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); + void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); + + void _setGUICursor(const std::string& name); + void _setCursorVisible(bool visible); + + typedef std::map CursorMap; + CursorMap mCursorMap; + + SDL_Cursor* mDebugCursor; + std::string mCurrentCursor; + bool mEnabled; + bool mInitialized; + bool mCursorVisible; + bool mDebug; + + }; +} + +#endif diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index b6761e883..529740d5e 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX @@ -28,8 +27,8 @@ namespace SFO mMouseY(0), mMouseX(0) { - _start(); _setupOISKeys(); + _start(); } InputWrapper::~InputWrapper() @@ -38,82 +37,60 @@ namespace SFO SDL_DestroyWindow(mSDLWindow); mSDLWindow = NULL; - CursorMap::const_iterator curs_iter = mCursorMap.begin(); - - while(curs_iter != mCursorMap.end()) - { - SDL_FreeCursor(curs_iter->second); - ++curs_iter; - } - - mCursorMap.clear(); - SDL_StopTextInput(); SDL_Quit(); } bool InputWrapper::_start() { - Uint32 flags = SDL_INIT_VIDEO; - if(SDL_WasInit(flags) == 0) - { - //get the HWND from ogre's renderwindow - size_t windowHnd; - mWindow->getCustomAttribute("WINDOW", &windowHnd); + //get the HWND from ogre's renderwindow + size_t windowHnd; + mWindow->getCustomAttribute("WINDOW", &windowHnd); - //kindly ask SDL not to trash our OGL context - //might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ? - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); - if(SDL_Init(SDL_INIT_VIDEO) != 0) - return false; + //wrap our own event handler around ogre's + mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); - //wrap our own event handler around ogre's - mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); - - if(mSDLWindow == NULL) - return false; + if(mSDLWindow == NULL) + return false; - //without this SDL will take ownership of the window and iconify it when - //we alt-tab away. - SDL_SetWindowFullscreen(mSDLWindow, 0); + //without this SDL will take ownership of the window and iconify it when + //we alt-tab away. + SDL_SetWindowFullscreen(mSDLWindow, 0); - //translate our keypresses into text - SDL_StartTextInput(); + //translate our keypresses into text + SDL_StartTextInput(); #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX - //linux-specific event-handling fixups - //see http://bugzilla.libsdl.org/show_bug.cgi?id=730 - SDL_SysWMinfo wm_info; - SDL_VERSION(&wm_info.version); + //linux-specific event-handling fixups + //see http://bugzilla.libsdl.org/show_bug.cgi?id=730 + SDL_SysWMinfo wm_info; + SDL_VERSION(&wm_info.version); - if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info)) - { - Display* display = wm_info.info.x11.display; - Window w = wm_info.info.x11.window; - - // Set the input hints so we get keyboard input - XWMHints *wmhints = XAllocWMHints(); - if (wmhints) { - wmhints->input = True; - wmhints->flags = InputHint; - XSetWMHints(display, w, wmhints); - XFree(wmhints); - } - - //make sure to subscribe to XLib's events - XSelectInput(display, w, - (FocusChangeMask | EnterWindowMask | LeaveWindowMask | - ExposureMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | KeyPressMask | KeyReleaseMask | - PropertyChangeMask | StructureNotifyMask | - KeymapStateMask)); - - XFlush(display); + if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info)) + { + Display* display = wm_info.info.x11.display; + Window w = wm_info.info.x11.window; + + // Set the input hints so we get keyboard input + XWMHints *wmhints = XAllocWMHints(); + if (wmhints) { + wmhints->input = True; + wmhints->flags = InputHint; + XSetWMHints(display, w, wmhints); + XFree(wmhints); } -#endif - SDL_ShowCursor(SDL_FALSE); - } + //make sure to subscribe to XLib's events + XSelectInput(display, w, + (FocusChangeMask | EnterWindowMask | LeaveWindowMask | + ExposureMask | ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | KeyPressMask | KeyReleaseMask | + PropertyChangeMask | StructureNotifyMask | + KeymapStateMask)); + + XFlush(display); + } +#endif return true; } @@ -209,10 +186,11 @@ namespace SFO //eep, wrap the pointer manually if the input driver doesn't support //relative positioning natively - if(SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == -1) + SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE); + + if(relative) { - if(relative) - mWrapPointer = true; + mWrapPointer = true; } //now remove all mouse events using the old setting from the queue @@ -222,118 +200,6 @@ namespace SFO SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION); } - bool InputWrapper::cursorChanged(const std::string &name) - { - CursorMap::const_iterator curs_iter = mCursorMap.find(name); - - //we have this cursor - if(curs_iter != mCursorMap.end()) - { - SDL_SetCursor(curs_iter->second); - return false; - } - else - { - //they should get back to use with more info - return true; - } - } - - void InputWrapper::cursorVisible(bool visible) - { - SDL_ShowCursor(visible ? SDL_TRUE : SDL_FALSE); - } - - void InputWrapper::receiveCursorInfo(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) - { - _createCursorFromResource(name, tex, size_x, size_y, hotspot_x, hotspot_y); - } - - /// \brief creates an SDL cursor from an Ogre texture - void InputWrapper::_createCursorFromResource(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) - { - //get the surfaces set up - Ogre::HardwarePixelBufferSharedPtr buffer = tex.get()->getBuffer(); - buffer.get()->lock(Ogre::HardwarePixelBuffer::HBL_READ_ONLY); - - std::string tempName = "_" + name + "_processing"; - - //we need to copy this to a temporary texture first because the cursors might be in DDS format, - //and Ogre doesn't have an interface to read DDS - Ogre::TexturePtr tempTexture = Ogre::TextureManager::getSingleton().createManual( - tempName, - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::TEX_TYPE_2D, - size_x, size_y, - 0, - Ogre::PF_FLOAT16_RGBA, - Ogre::TU_STATIC); - - tempTexture->getBuffer()->blit(buffer); - buffer->unlock(); - - // now blit to memory - Ogre::Image destImage; - tempTexture->convertToImage(destImage); - - SDL_Surface* surf = SDL_CreateRGBSurface(0,size_x,size_y,32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF); - - - //copy the Ogre texture to an SDL surface - for(size_t x = 0; x < size_x; ++x) - { - for(size_t y = 0; y < size_y; ++y) - { - Ogre::ColourValue clr = destImage.getColourAt(x, y, 0); - - //set the pixel on the SDL surface to the same value as the Ogre texture's - _putPixel(surf, x, y, SDL_MapRGBA(surf->format, clr.r*255, clr.g*255, clr.b*255, clr.a*255)); - } - } - - //set the cursor and store it for later - SDL_Cursor* curs = SDL_CreateColorCursor(surf, hotspot_x, hotspot_y); - SDL_SetCursor(curs); - mCursorMap.insert(CursorMap::value_type(std::string(name), curs)); - - //clean up - SDL_FreeSurface(surf); - Ogre::TextureManager::getSingleton().remove(tempName); - } - - void InputWrapper::_putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) - { - int bpp = surface->format->BytesPerPixel; - /* Here p is the address to the pixel we want to set */ - Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; - - switch(bpp) { - case 1: - *p = pixel; - break; - - case 2: - *(Uint16 *)p = pixel; - break; - - case 3: - if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { - p[0] = (pixel >> 16) & 0xff; - p[1] = (pixel >> 8) & 0xff; - p[2] = pixel & 0xff; - } else { - p[0] = pixel & 0xff; - p[1] = (pixel >> 8) & 0xff; - p[2] = (pixel >> 16) & 0xff; - } - break; - - case 4: - *(Uint32 *)p = pixel; - break; - } - } - /// \brief Internal method for ignoring relative motions as a side effect /// of warpMouse() bool InputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt) diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index d37a43e33..5233fee8b 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -1,7 +1,8 @@ -#ifndef _MWINPUT_SDLINPUTWRAPPER_H -#define _MWINPUT_SDLINPUTWRAPPER_H +#ifndef _SDL4OGRE_SDLINPUTWRAPPER_H +#define _SDL4OGRE_SDLINPUTWRAPPER_H #include "SDL2/SDL_events.h" + #include #include @@ -9,36 +10,14 @@ #include "events.h" -namespace Ogre -{ - class Texture; -} namespace SFO { - - - class CursorChangeClient - { - public: - /// \brief Tell the client that the cursor has changed, giving the - /// name of the cursor we changed to ("arrow", "ibeam", etc) - /// \return Whether the client is interested in more information about the cursor - virtual bool cursorChanged(const std::string &name) = 0; - - /// \brief Follow up a cursorChanged() call with enough info to create an SDL cursor. - virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0; - - /// \brief Tell the client when the cursor visibility changed - virtual void cursorVisible(bool visible) = 0; - }; - - class InputWrapper : - public CursorChangeClient + class InputWrapper { public: InputWrapper(Ogre::RenderWindow* window); - virtual ~InputWrapper(); + ~InputWrapper(); void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; } void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; } @@ -51,10 +30,6 @@ namespace SFO bool getMouseRelative() { return mMouseRelative; } void setGrabPointer(bool grab); - virtual bool cursorChanged(const std::string &name); - virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); - virtual void cursorVisible(bool visible); - OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code); void warpMouse(int x, int y); @@ -66,9 +41,6 @@ namespace SFO void _wrapMousePointer(const SDL_MouseMotionEvent &evt); MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); - void _createCursorFromResource(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); - void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); - void _handleKeyPress(SDL_KeyboardEvent& evt); Uint32 _UTF8ToUTF32(const unsigned char *buf); void _setupOISKeys(); @@ -80,9 +52,6 @@ namespace SFO typedef boost::unordered_map KeyMap; KeyMap mKeyMap; - typedef std::map CursorMap; - CursorMap mCursorMap; - Uint16 mWarpX; Uint16 mWarpY; bool mWarpCompensate; From eb08f407d3510ba0e6ccd67feb9f6a4ee5914ab7 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Sat, 12 Jan 2013 15:38:22 -0400 Subject: [PATCH 019/213] Oops, remove resource leak in the input wrapper. --- extern/sdl4ogre/sdlinputwrapper.cpp | 33 +++++++++++------------------ extern/sdl4ogre/sdlinputwrapper.hpp | 1 - 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 529740d5e..0a0e321bb 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -28,21 +28,7 @@ namespace SFO mMouseX(0) { _setupOISKeys(); - _start(); - } - - InputWrapper::~InputWrapper() - { - if(mSDLWindow != NULL) - SDL_DestroyWindow(mSDLWindow); - mSDLWindow = NULL; - - SDL_StopTextInput(); - SDL_Quit(); - } - bool InputWrapper::_start() - { //get the HWND from ogre's renderwindow size_t windowHnd; mWindow->getCustomAttribute("WINDOW", &windowHnd); @@ -50,12 +36,11 @@ namespace SFO //wrap our own event handler around ogre's mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); - if(mSDLWindow == NULL) - return false; + assert(mSDLWindow != NULL); //without this SDL will take ownership of the window and iconify it when //we alt-tab away. - SDL_SetWindowFullscreen(mSDLWindow, 0); + //SDL_SetWindowFullscreen(mSDLWindow, 0); //translate our keypresses into text SDL_StartTextInput(); @@ -91,14 +76,20 @@ namespace SFO XFlush(display); } #endif - return true; } - void InputWrapper::capture() + InputWrapper::~InputWrapper() { - if(!_start()) - throw std::runtime_error(SDL_GetError()); + if(mSDLWindow != NULL) + SDL_DestroyWindow(mSDLWindow); + mSDLWindow = NULL; + SDL_StopTextInput(); + SDL_Quit(); + } + + void InputWrapper::capture() + { SDL_Event evt; while(SDL_PollEvent(&evt)) { diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index 5233fee8b..d3c172b49 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -35,7 +35,6 @@ namespace SFO void warpMouse(int x, int y); private: - bool _start(); bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); void _wrapMousePointer(const SDL_MouseMotionEvent &evt); From b6ec64485c21689375ee7823dc05794bb594c47c Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Sat, 12 Jan 2013 17:52:26 -0400 Subject: [PATCH 020/213] fix includes for Windows --- apps/openmw/engine.cpp | 4 +++- apps/openmw/mwgui/windowmanagerimp.cpp | 4 ++-- cmake/FindSDL2.cmake | 1 + extern/oics/ICSPrerequisites.h | 10 +++++----- extern/sdl4ogre/OISCompat.h | 4 ++-- extern/sdl4ogre/cursormanager.hpp | 2 +- extern/sdl4ogre/events.h | 2 +- extern/sdl4ogre/sdlcursormanager.hpp | 2 +- extern/sdl4ogre/sdlinputwrapper.cpp | 2 +- extern/sdl4ogre/sdlinputwrapper.hpp | 4 ++-- 10 files changed, 19 insertions(+), 16 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 51dbabba5..042d10a93 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -1,4 +1,7 @@ #include "engine.hpp" + +#include + #include "components/esm/loadcell.hpp" #include @@ -36,7 +39,6 @@ #include "mwmechanics/mechanicsmanagerimp.hpp" -#include "SDL2/SDL.h" void OMW::Engine::executeLocalScripts() diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 20301b1b2..e096ee1fb 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -4,8 +4,8 @@ #include #include "MyGUI_UString.h" -#include "MYGUI/MyGUI_IPointer.h" -#include "MYGUI/MyGUI_ResourceImageSetPointer.h" +#include "MyGUI_IPointer.h" +#include "MyGUI_ResourceImageSetPointer.h" #include "MyGUI_TextureUtility.h" #include diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake index 614426ccc..707f5bc3d 100644 --- a/cmake/FindSDL2.cmake +++ b/cmake/FindSDL2.cmake @@ -70,6 +70,7 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) + FIND_PATH(SDL2_INCLUDE_DIR SDL.h HINTS $ENV{SDL2DIR} diff --git a/extern/oics/ICSPrerequisites.h b/extern/oics/ICSPrerequisites.h index 82c95c86a..2e107355a 100644 --- a/extern/oics/ICSPrerequisites.h +++ b/extern/oics/ICSPrerequisites.h @@ -39,11 +39,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tinyxml.h" -#include "SDL2/SDL_input.h" -#include "SDL2/SDL_keyboard.h" -#include "SDL2/SDL_mouse.h" -#include "SDL2/SDL_joystick.h" -#include "SDL2/SDL_events.h" +#include "SDL_input.h" +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_events.h" /// Define the dll export qualifier if compiling for Windows diff --git a/extern/sdl4ogre/OISCompat.h b/extern/sdl4ogre/OISCompat.h index 04ba2c537..3cffa143d 100644 --- a/extern/sdl4ogre/OISCompat.h +++ b/extern/sdl4ogre/OISCompat.h @@ -1,8 +1,8 @@ #ifndef _OIS_SDL_COMPAT_H #define _OIS_SDL_COMPAT_H -#include -#include +#include +#include namespace OIS { diff --git a/extern/sdl4ogre/cursormanager.hpp b/extern/sdl4ogre/cursormanager.hpp index 938f5f4c2..b98d69ce3 100644 --- a/extern/sdl4ogre/cursormanager.hpp +++ b/extern/sdl4ogre/cursormanager.hpp @@ -1,7 +1,7 @@ #ifndef _SDL4OGRE_CURSOR_MANAGER_H #define _SDL4OGRE_CURSOR_MANAGER_H -#include "SDL2/SDL_types.h" +#include #include namespace Ogre diff --git a/extern/sdl4ogre/events.h b/extern/sdl4ogre/events.h index 945daf49a..5a0146635 100644 --- a/extern/sdl4ogre/events.h +++ b/extern/sdl4ogre/events.h @@ -1,7 +1,7 @@ #ifndef _SFO_EVENTS_H #define _SFO_EVENTS_H -#include +#include //////////// diff --git a/extern/sdl4ogre/sdlcursormanager.hpp b/extern/sdl4ogre/sdlcursormanager.hpp index 2de192377..ad371f551 100644 --- a/extern/sdl4ogre/sdlcursormanager.hpp +++ b/extern/sdl4ogre/sdlcursormanager.hpp @@ -1,7 +1,7 @@ #ifndef _SDL4OGRE_CURSORMANAGER_H #define _SDL4OGRE_CURSORMANAGER_H -#include "SDL.h" +#include #include "cursormanager.hpp" #include diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 0a0e321bb..da65102e7 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -1,5 +1,5 @@ #include "sdlinputwrapper.hpp" -#include +#include #include #include diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index d3c172b49..9154ff847 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -1,9 +1,9 @@ #ifndef _SDL4OGRE_SDLINPUTWRAPPER_H #define _SDL4OGRE_SDLINPUTWRAPPER_H -#include "SDL2/SDL_events.h" +#include -#include +#include #include #include "OISCompat.h" From 2639bc43839154810a5cacda6d0085e03f0aa9ae Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Sat, 12 Jan 2013 18:53:00 -0400 Subject: [PATCH 021/213] Another temp fix for windows --- cmake/FindSDL2.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake index 707f5bc3d..e0c7feea3 100644 --- a/cmake/FindSDL2.cmake +++ b/cmake/FindSDL2.cmake @@ -166,6 +166,10 @@ IF(SDL2_LIBRARY_TEMP) IF(MINGW) SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) ENDIF(MINGW) + + IF(WIN32) + SET(SDL2_LIBRARY_TEMP winmm imm32 version msimg32 ${SDL2_LIBRARY_TEMP}) + ENDIF(WIN32) # Set the final string here so the GUI reflects the final state. SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") From 043e29c62089159061d74213e055f2c521d68272 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Sun, 13 Jan 2013 21:32:45 -0400 Subject: [PATCH 022/213] Have SDL manage the window instead of OGRE to work around SDL Windows bugs (grumble) --- apps/openmw/engine.cpp | 90 ++++++++++++++++++++++++----- apps/openmw/engine.hpp | 2 + extern/sdl4ogre/sdlinputwrapper.cpp | 23 +------- libs/openengine/ogre/renderer.cpp | 64 +++++++++++++++++++- libs/openengine/ogre/renderer.hpp | 7 +++ 5 files changed, 150 insertions(+), 36 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 12a5d4be7..0619281d0 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -1,7 +1,5 @@ #include "engine.hpp" -#include - #include "components/esm/loadcell.hpp" #include @@ -40,6 +38,7 @@ #include "mwmechanics/mechanicsmanagerimp.hpp" +#include void OMW::Engine::executeLocalScripts() { @@ -70,6 +69,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) { try { + handleSDLMessages(); + mEnvironment.setFrameDuration (evt.timeSinceLastFrame); // update input @@ -116,6 +117,9 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), tri, batch); MWBase::Environment::get().getWindowManager()->onFrame(evt.timeSinceLastFrame); + + //Flush any events that weren't handled this frame + SDL_FlushEvents(0x0, 0xFFFFFFFF); } catch (const std::exception& e) { @@ -125,6 +129,65 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) return true; } +void OMW::Engine::handleSDLMessages() +{ + //Pump messages since the last frame + const int max_events = 20; + SDL_Event events[max_events]; + + SDL_PumpEvents(); + int num_events = SDL_PeepEvents(events, max_events, SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT); + + bool move_or_resize = false; + + unsigned int size_x = 0; + unsigned int size_y = 0; + + if(num_events != 0) + { + for(int i=0; i < num_events; ++i) + { + switch(events[i].window.event) + { + case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_MOVED: + printf("Resizing window!\n"); + move_or_resize = true; + size_x = events[i].window.data1; + size_y = events[i].window.data2; + break; + } + } + } + + //handle window movements + if(move_or_resize) + { + mOgre->adjustViewport(); + if(!mOgre->getWindow()->isFullScreen()) + { + SDL_DisplayMode dispMode; + SDL_Window* sdlWindow = mOgre->getSDLWindow(); + + SDL_GetWindowDisplayMode(sdlWindow, &dispMode); + + dispMode.w = size_x; + dispMode.h = size_y; + + SDL_SetWindowDisplayMode(sdlWindow, &dispMode); + + mOgre->getWindow()->windowMovedOrResized(); + mOgre->getWindow()->resize(size_x, size_y); + } + } + + if(SDL_PeepEvents(NULL, 1, SDL_PEEKEVENT, SDL_QUIT, SDL_QUIT) != 0) + { + //user requested a quit, break out. + mOgre->getRoot()->queueEndRendering(); + } +} + OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) : mOgre (0) , mFpsLevel(0) @@ -140,6 +203,16 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) { std::srand ( std::time(NULL) ); MWClass::registerClasses(); + + Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE; + if(SDL_WasInit(flags) == 0) + { + //kindly ask SDL not to trash our OGL context + //might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ? + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); + if(SDL_Init(flags) != 0) + throw std::runtime_error("Couldn't initialize SDL!"); + } } OMW::Engine::~Engine() @@ -147,6 +220,7 @@ OMW::Engine::~Engine() mEnvironment.cleanup(); delete mScriptContext; delete mOgre; + SDL_Quit(); } // Load all BSA files in data directory. @@ -317,7 +391,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) addResourcesDirectory(mResDir / "shadows"); addZipResource(mResDir / "mygui" / "Obliviontt.zip"); - // Create the window OEngine::Render::WindowSettings windowSettings; windowSettings.fullscreen = settings.getBool("fullscreen", "Video"); windowSettings.window_x = settings.getInt("resolution x", "Video"); @@ -325,20 +398,11 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) windowSettings.vsync = settings.getBool("vsync", "Video"); std::string aa = settings.getString("antialiasing", "Video"); windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0"; + mOgre->createWindow("OpenMW", windowSettings); loadBSA(); - Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE; - if(SDL_WasInit(flags) == 0) - { - //kindly ask SDL not to trash our OGL context - //might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ? - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); - if(SDL_Init(flags) != 0) - throw std::runtime_error("Couldn't initialize SDL!"); - } - // cursor replacer (converts the cursor from the bsa so they can be used by mygui) MWGui::CursorReplace replacer; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index e320c6991..971445147 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -103,6 +103,8 @@ namespace OMW void executeLocalScripts(); + void handleSDLMessages(); + virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); /// Load settings from various files, returns the path to the user settings file diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index da65102e7..cf864b20f 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -85,7 +85,6 @@ namespace SFO mSDLWindow = NULL; SDL_StopTextInput(); - SDL_Quit(); } void InputWrapper::capture() @@ -121,24 +120,6 @@ namespace SFO case SDL_KEYUP: mKeyboardListener->keyReleased(evt.key); break; - - case SDL_WINDOWEVENT_FOCUS_GAINED: - mWindowListener->windowFocusChange(true); - break; - case SDL_WINDOWEVENT_FOCUS_LOST: - mWindowListener->windowFocusChange(false); - break; - case SDL_WINDOWEVENT_EXPOSED: - mWindowListener->windowVisibilityChange(true); - break; - case SDL_WINDOWEVENT_HIDDEN: - mWindowListener->windowVisibilityChange(false); - break; - - //SDL traps ^C signals, pass it to OGRE. - case SDL_QUIT: - Ogre::Root::getSingleton().queueEndRendering(); - break; } } } @@ -186,9 +167,7 @@ namespace SFO //now remove all mouse events using the old setting from the queue SDL_PumpEvents(); - - SDL_Event dummy[20]; - SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION); + SDL_FlushEvent(SDL_MOUSEMOTION); } /// \brief Internal method for ignoring relative motions as a side effect diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 3cdb00518..7696095eb 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -1,6 +1,9 @@ #include "renderer.hpp" #include "fader.hpp" +#include +#include + #include "OgreRoot.h" #include "OgreRenderWindow.h" #include "OgreLogManager.h" @@ -47,11 +50,16 @@ void OgreRenderer::cleanup() delete mRoot; mRoot = NULL; + SDL_DestroyWindow(mSDLWindow); + mSDLWindow = NULL; + unloadPlugins(); } void OgreRenderer::start() { + //TODO: Check if we still need to do this if we're using SDL's + //message pump #if defined(__APPLE__) && !defined(__LP64__) // OSX Carbon Message Pump do { @@ -214,6 +222,56 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& params.insert(std::make_pair("FSAA", settings.fsaa)); params.insert(std::make_pair("vsync", settings.vsync ? "true" : "false")); + // Create an application window with the following settings: + SDL_Window *window = SDL_CreateWindow( + "OpenMW", // window title + SDL_WINDOWPOS_UNDEFINED, // initial x position + SDL_WINDOWPOS_UNDEFINED, // initial y position + settings.window_x, // width, in pixels + settings.window_y, // height, in pixels + SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE + | (settings.fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0) + ); + + + //get the native whnd + struct SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + + if(-1 == SDL_GetWindowWMInfo(window, &wmInfo)) + throw std::runtime_error("Couldn't get WM Info!"); + + Ogre::String winHandle; + + switch(wmInfo.subsystem) + { +#ifdef WIN32 + case SDL_SYSWM_WINDOWS: + // Windows code + winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.win.window); + break; +#elif MACOS + case SDL_SYSWM_COCOA: + //required to make OGRE play nice with our window + params.insert(std::make_pair("macAPI", "cocoa")); + params.insert(std::make_pair("macAPICocoaUseNSView", "true")); + + winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.cocoa.window); + break; +#else + case SDL_SYSWM_X11: + winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.x11.display); + winHandle += ":0:"; + winHandle += Ogre::StringConverter::toString((unsigned long)wmInfo.info.x11.window); + break; +#endif + default: + throw std::runtime_error("Unexpected WM!"); + break; + } + + params.insert(std::make_pair("externalWindowHandle", winHandle)); + mWindow = mRoot->createRenderWindow(title, settings.window_x, settings.window_y, settings.fullscreen, ¶ms); // create the semi-transparent black background texture used by the GUI. @@ -253,7 +311,11 @@ void OgreRenderer::createScene(const std::string& camName, float fov, float near void OgreRenderer::adjustViewport() { // Alter the camera aspect ratio to match the viewport - mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight())); + if(mCamera != NULL) + { + mView->setDimensions(0, 0, 1, 1); + mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight())); + } } void OgreRenderer::setWindowEventListener(Ogre::WindowEventListener* listener) diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index a8788dfca..7e57af927 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -31,6 +31,8 @@ #include #endif +struct SDL_Window; + namespace Ogre { #if !defined(__APPLE__) || defined(__LP64__) @@ -74,6 +76,7 @@ namespace OEngine Ogre::Root *mRoot; #endif Ogre::RenderWindow *mWindow; + SDL_Window *mSDLWindow; Ogre::SceneManager *mScene; Ogre::Camera *mCamera; Ogre::Viewport *mView; @@ -99,6 +102,7 @@ namespace OEngine OgreRenderer() : mRoot(NULL) , mWindow(NULL) + , mSDLWindow(NULL) , mScene(NULL) , mCamera(NULL) , mView(NULL) @@ -169,6 +173,9 @@ namespace OEngine /// Get the rendering window Ogre::RenderWindow *getWindow() { return mWindow; } + /// Get the SDL Window + SDL_Window *getSDLWindow() { return mSDLWindow; } + /// Get the scene manager Ogre::SceneManager *getScene() { return mScene; } From 9b485a86ef8e7f5b96f89b78e5fe6a8f18629cbf Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Sun, 13 Jan 2013 22:38:22 -0400 Subject: [PATCH 023/213] resize the window in a slightly less bad way, fix my check in setUseHardwareCursors to be the right way round --- apps/openmw/engine.cpp | 19 ++++--------------- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 0619281d0..7d08eda03 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -138,7 +138,7 @@ void OMW::Engine::handleSDLMessages() SDL_PumpEvents(); int num_events = SDL_PeepEvents(events, max_events, SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT); - bool move_or_resize = false; + bool resize = false; unsigned int size_x = 0; unsigned int size_y = 0; @@ -150,9 +150,8 @@ void OMW::Engine::handleSDLMessages() switch(events[i].window.event) { case SDL_WINDOWEVENT_RESIZED: - case SDL_WINDOWEVENT_MOVED: printf("Resizing window!\n"); - move_or_resize = true; + resize = true; size_x = events[i].window.data1; size_y = events[i].window.data2; break; @@ -161,23 +160,13 @@ void OMW::Engine::handleSDLMessages() } //handle window movements - if(move_or_resize) + if(resize) { - mOgre->adjustViewport(); if(!mOgre->getWindow()->isFullScreen()) { - SDL_DisplayMode dispMode; - SDL_Window* sdlWindow = mOgre->getSDLWindow(); - - SDL_GetWindowDisplayMode(sdlWindow, &dispMode); - - dispMode.w = size_x; - dispMode.h = size_y; - - SDL_SetWindowDisplayMode(sdlWindow, &dispMode); - mOgre->getWindow()->windowMovedOrResized(); mOgre->getWindow()->resize(size_x, size_y); + mOgre->adjustViewport(); } } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index e096ee1fb..dbd8e01a2 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -750,7 +750,7 @@ void WindowManager::setUseHardwareCursors(bool use) { mCursorManager->setEnabled(use); - if(!use) + if(use) { MyGUI::PointerManager::getInstance().setVisible(false); } From 10a3caa50494b0abe3776496fb72dcd5ef73d4f0 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Sun, 13 Jan 2013 23:38:46 -0400 Subject: [PATCH 024/213] more resizing fixes from scrawl, share an SDLWindow between the input wrapper and the engine --- apps/openmw/engine.cpp | 10 +---- apps/openmw/mwinput/inputmanagerimp.cpp | 5 +-- apps/openmw/mwinput/inputmanagerimp.hpp | 1 - apps/openmw/mwrender/renderingmanager.cpp | 1 - extern/sdl4ogre/sdlinputwrapper.cpp | 49 ++++++++++++++--------- extern/sdl4ogre/sdlinputwrapper.hpp | 6 ++- libs/openengine/ogre/renderer.cpp | 4 +- 7 files changed, 39 insertions(+), 37 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 7d08eda03..3374ba304 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -150,7 +150,6 @@ void OMW::Engine::handleSDLMessages() switch(events[i].window.event) { case SDL_WINDOWEVENT_RESIZED: - printf("Resizing window!\n"); resize = true; size_x = events[i].window.data1; size_y = events[i].window.data2; @@ -162,12 +161,7 @@ void OMW::Engine::handleSDLMessages() //handle window movements if(resize) { - if(!mOgre->getWindow()->isFullScreen()) - { - mOgre->getWindow()->windowMovedOrResized(); - mOgre->getWindow()->resize(size_x, size_y); - mOgre->adjustViewport(); - } + mOgre->getWindow()->resize(size_x, size_y); } if(SDL_PeepEvents(NULL, 1, SDL_PEEKEVENT, SDL_QUIT, SDL_QUIT) != 0) @@ -436,7 +430,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mEnvironment.setInputManager (new MWInput::InputManager (*mOgre, MWBase::Environment::get().getWorld()->getPlayer(), - *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists)); + *MWBase::Environment::get().getWindowManager(), *this, keybinderUser, keybinderUserExists)); // load cell ESM::Position pos; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 9d80de91e..ab873c686 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -31,7 +31,6 @@ namespace MWInput InputManager::InputManager(OEngine::Render::OgreRenderer &ogre, MWWorld::Player &player, MWBase::WindowManager &windows, - bool debug, OMW::Engine& engine, const std::string& userFile, bool userFileExists) : mOgre(ogre) @@ -45,7 +44,7 @@ namespace MWInput , mUserFile(userFile) , mDragDrop(false) , mGuiCursorEnabled(false) - , mDebug(debug) + , mDebug(Settings::Manager::getBool("debug", "Engine")) , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input")) @@ -63,7 +62,7 @@ namespace MWInput Ogre::RenderWindow* window = ogre.getWindow (); - mInputManager = new SFO::InputWrapper(window); + mInputManager = new SFO::InputWrapper(mOgre.getSDLWindow()); mInputManager->setMouseEventCallback (this); mInputManager->setKeyboardEventCallback (this); mInputManager->setWindowEventCallback(this); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 34ea92a37..9832be9a6 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -62,7 +62,6 @@ namespace MWInput InputManager(OEngine::Render::OgreRenderer &_ogre, MWWorld::Player&_player, MWBase::WindowManager &_windows, - bool debug, OMW::Engine& engine, const std::string& userFile, bool userFileExists); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ae7d6612b..5d2a5c951 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -839,7 +839,6 @@ void RenderingManager::windowResized(Ogre::RenderWindow* rw) Settings::Manager::setInt("resolution x", "Video", rw->getWidth()); Settings::Manager::setInt("resolution y", "Video", rw->getHeight()); - mRendering.adjustViewport(); mCompositors->recreate(); mWater->assignTextures(); diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index cf864b20f..464d8cb6a 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -16,9 +16,9 @@ namespace SFO { /// \brief General purpose wrapper for OGRE applications around SDL's event /// queue, mostly used for handling input-related events. - InputWrapper::InputWrapper(Ogre::RenderWindow *window) : - mWindow(window), - mSDLWindow(NULL), + InputWrapper::InputWrapper(SDL_Window* window) : + mSDLWindow(window), + mOwnWindow(false), mWarpCompensate(false), mMouseRelative(false), mGrabPointer(false), @@ -29,9 +29,27 @@ namespace SFO { _setupOISKeys(); + SDL_StartTextInput(); + } + + InputWrapper::~InputWrapper() + { + if(mSDLWindow != NULL && mOwnWindow) + SDL_DestroyWindow(mSDLWindow); + mSDLWindow = NULL; + + SDL_StopTextInput(); + } + + void InputWrapper::initFromRenderWindow(Ogre::RenderWindow *win) + { + assert(mSDLWindow == NULL); + + mOwnWindow = true; + //get the HWND from ogre's renderwindow size_t windowHnd; - mWindow->getCustomAttribute("WINDOW", &windowHnd); + win->getCustomAttribute("WINDOW", &windowHnd); //wrap our own event handler around ogre's mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); @@ -42,9 +60,6 @@ namespace SFO //we alt-tab away. //SDL_SetWindowFullscreen(mSDLWindow, 0); - //translate our keypresses into text - SDL_StartTextInput(); - #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX //linux-specific event-handling fixups //see http://bugzilla.libsdl.org/show_bug.cgi?id=730 @@ -78,15 +93,6 @@ namespace SFO #endif } - InputWrapper::~InputWrapper() - { - if(mSDLWindow != NULL) - SDL_DestroyWindow(mSDLWindow); - mSDLWindow = NULL; - - SDL_StopTextInput(); - } - void InputWrapper::capture() { SDL_Event evt; @@ -158,11 +164,14 @@ namespace SFO //eep, wrap the pointer manually if the input driver doesn't support //relative positioning natively - SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE); + int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE); if(relative) { - mWrapPointer = true; + if(success != 0) + { + mWrapPointer = true; + } } //now remove all mouse events using the old setting from the queue @@ -200,8 +209,8 @@ namespace SFO SDL_GetWindowSize(mSDLWindow, &width, &height); - const int FUDGE_FACTOR_X = width / 4; - const int FUDGE_FACTOR_Y = height / 4; + const int FUDGE_FACTOR_X = width / 8; + const int FUDGE_FACTOR_Y = height / 8; //warp the mouse if it's about to go outside the window if(evt.x - FUDGE_FACTOR_X < 0 || evt.x + FUDGE_FACTOR_X > width diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index 9154ff847..db4e6f9b0 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -16,9 +16,11 @@ namespace SFO class InputWrapper { public: - InputWrapper(Ogre::RenderWindow* window); + InputWrapper(SDL_Window *window=NULL); ~InputWrapper(); + void initFromRenderWindow(Ogre::RenderWindow* win); + void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; } void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; } void setWindowEventCallback(WindowListener* listen) { mWindowListener = listen; } @@ -62,8 +64,8 @@ namespace SFO Sint32 mMouseX; Sint32 mMouseY; - Ogre::RenderWindow* mWindow; SDL_Window* mSDLWindow; + bool mOwnWindow; }; } diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 7696095eb..0f29b15a0 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -223,7 +223,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& params.insert(std::make_pair("vsync", settings.vsync ? "true" : "false")); // Create an application window with the following settings: - SDL_Window *window = SDL_CreateWindow( + mSDLWindow = SDL_CreateWindow( "OpenMW", // window title SDL_WINDOWPOS_UNDEFINED, // initial x position SDL_WINDOWPOS_UNDEFINED, // initial y position @@ -238,7 +238,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& struct SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); - if(-1 == SDL_GetWindowWMInfo(window, &wmInfo)) + if(-1 == SDL_GetWindowWMInfo(mSDLWindow, &wmInfo)) throw std::runtime_error("Couldn't get WM Info!"); Ogre::String winHandle; From 3731ec0541998dab62ee0cf464ddaca4f03237ef Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 21 Mar 2013 19:54:26 +0100 Subject: [PATCH 025/213] Praying to God. --- files/opencs/scalable/Palette.svg | 569 ++++++ .../referenceable record type/.directory | 5 + .../referenceable record type/activator.svg | 1088 ++++++++++++ .../referenceable record type/apparatus.svg | 1058 +++++++++++ .../referenceable record type/book.svg | 692 ++++++++ .../referenceable record type/container.svg | 1359 +++++++++++++++ .../light source.svg | 1543 +++++++++++++++++ .../referenceable record type/potion.svg | 1052 +++++++++++ .../referenceable record type/static.svg | 1141 ++++++++++++ .../referenceable record type/weapon.svg | 1175 +++++++++++++ 10 files changed, 9682 insertions(+) create mode 100644 files/opencs/scalable/Palette.svg create mode 100644 files/opencs/scalable/referenceable record type/.directory create mode 100644 files/opencs/scalable/referenceable record type/activator.svg create mode 100644 files/opencs/scalable/referenceable record type/apparatus.svg create mode 100644 files/opencs/scalable/referenceable record type/book.svg create mode 100644 files/opencs/scalable/referenceable record type/container.svg create mode 100644 files/opencs/scalable/referenceable record type/light source.svg create mode 100644 files/opencs/scalable/referenceable record type/potion.svg create mode 100644 files/opencs/scalable/referenceable record type/static.svg create mode 100644 files/opencs/scalable/referenceable record type/weapon.svg diff --git a/files/opencs/scalable/Palette.svg b/files/opencs/scalable/Palette.svg new file mode 100644 index 000000000..f42475330 --- /dev/null +++ b/files/opencs/scalable/Palette.svg @@ -0,0 +1,569 @@ + + + + + + + image/svg+xml + + + + + + Tango Palette + + + Tuomas Kuosmanen + + + + + Garrett Le Sage +Kenneth Wimer +Jakub Steiner + + +http://www.tango-project.org/files/Tango-Palette.svg + + + unify + global + theme + color + palette + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/files/opencs/scalable/referenceable record type/.directory b/files/opencs/scalable/referenceable record type/.directory new file mode 100644 index 000000000..e2d80ed58 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/.directory @@ -0,0 +1,5 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2013,3,21,10,19,49 +Version=3 +ViewMode=1 diff --git a/files/opencs/scalable/referenceable record type/activator.svg b/files/opencs/scalable/referenceable record type/activator.svg new file mode 100644 index 000000000..0c6db59a7 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/activator.svg @@ -0,0 +1,1088 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/apparatus.svg b/files/opencs/scalable/referenceable record type/apparatus.svg new file mode 100644 index 000000000..37cef0e89 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/apparatus.svg @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/book.svg b/files/opencs/scalable/referenceable record type/book.svg new file mode 100644 index 000000000..8c041a9e7 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/book.svg @@ -0,0 +1,692 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/container.svg b/files/opencs/scalable/referenceable record type/container.svg new file mode 100644 index 000000000..11ad79438 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/container.svg @@ -0,0 +1,1359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/light source.svg b/files/opencs/scalable/referenceable record type/light source.svg new file mode 100644 index 000000000..8575659f4 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/light source.svg @@ -0,0 +1,1543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/potion.svg b/files/opencs/scalable/referenceable record type/potion.svg new file mode 100644 index 000000000..888006531 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/potion.svg @@ -0,0 +1,1052 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/static.svg b/files/opencs/scalable/referenceable record type/static.svg new file mode 100644 index 000000000..a6f29370f --- /dev/null +++ b/files/opencs/scalable/referenceable record type/static.svg @@ -0,0 +1,1141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/weapon.svg b/files/opencs/scalable/referenceable record type/weapon.svg new file mode 100644 index 000000000..1e5aaac41 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/weapon.svg @@ -0,0 +1,1175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + From e46097cd2ed1e1742d63a2d958c8cec6a68645f1 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 21 Mar 2013 19:54:26 +0100 Subject: [PATCH 026/213] Icons. Currently activator, apparatus, book, container (work in progress), light source, potion, static, weapon. --- files/opencs/scalable/Palette.svg | 569 ++++++ .../referenceable record type/.directory | 5 + .../referenceable record type/activator.svg | 1088 ++++++++++++ .../referenceable record type/apparatus.svg | 1058 +++++++++++ .../referenceable record type/book.svg | 692 ++++++++ .../referenceable record type/container.svg | 1359 +++++++++++++++ .../light source.svg | 1543 +++++++++++++++++ .../referenceable record type/potion.svg | 1052 +++++++++++ .../referenceable record type/static.svg | 1141 ++++++++++++ .../referenceable record type/weapon.svg | 1175 +++++++++++++ 10 files changed, 9682 insertions(+) create mode 100644 files/opencs/scalable/Palette.svg create mode 100644 files/opencs/scalable/referenceable record type/.directory create mode 100644 files/opencs/scalable/referenceable record type/activator.svg create mode 100644 files/opencs/scalable/referenceable record type/apparatus.svg create mode 100644 files/opencs/scalable/referenceable record type/book.svg create mode 100644 files/opencs/scalable/referenceable record type/container.svg create mode 100644 files/opencs/scalable/referenceable record type/light source.svg create mode 100644 files/opencs/scalable/referenceable record type/potion.svg create mode 100644 files/opencs/scalable/referenceable record type/static.svg create mode 100644 files/opencs/scalable/referenceable record type/weapon.svg diff --git a/files/opencs/scalable/Palette.svg b/files/opencs/scalable/Palette.svg new file mode 100644 index 000000000..f42475330 --- /dev/null +++ b/files/opencs/scalable/Palette.svg @@ -0,0 +1,569 @@ + + + + + + + image/svg+xml + + + + + + Tango Palette + + + Tuomas Kuosmanen + + + + + Garrett Le Sage +Kenneth Wimer +Jakub Steiner + + +http://www.tango-project.org/files/Tango-Palette.svg + + + unify + global + theme + color + palette + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/files/opencs/scalable/referenceable record type/.directory b/files/opencs/scalable/referenceable record type/.directory new file mode 100644 index 000000000..e2d80ed58 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/.directory @@ -0,0 +1,5 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2013,3,21,10,19,49 +Version=3 +ViewMode=1 diff --git a/files/opencs/scalable/referenceable record type/activator.svg b/files/opencs/scalable/referenceable record type/activator.svg new file mode 100644 index 000000000..0c6db59a7 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/activator.svg @@ -0,0 +1,1088 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/apparatus.svg b/files/opencs/scalable/referenceable record type/apparatus.svg new file mode 100644 index 000000000..37cef0e89 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/apparatus.svg @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/book.svg b/files/opencs/scalable/referenceable record type/book.svg new file mode 100644 index 000000000..8c041a9e7 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/book.svg @@ -0,0 +1,692 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/container.svg b/files/opencs/scalable/referenceable record type/container.svg new file mode 100644 index 000000000..11ad79438 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/container.svg @@ -0,0 +1,1359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/light source.svg b/files/opencs/scalable/referenceable record type/light source.svg new file mode 100644 index 000000000..8575659f4 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/light source.svg @@ -0,0 +1,1543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/potion.svg b/files/opencs/scalable/referenceable record type/potion.svg new file mode 100644 index 000000000..888006531 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/potion.svg @@ -0,0 +1,1052 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/static.svg b/files/opencs/scalable/referenceable record type/static.svg new file mode 100644 index 000000000..a6f29370f --- /dev/null +++ b/files/opencs/scalable/referenceable record type/static.svg @@ -0,0 +1,1141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/weapon.svg b/files/opencs/scalable/referenceable record type/weapon.svg new file mode 100644 index 000000000..1e5aaac41 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/weapon.svg @@ -0,0 +1,1175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + From df8600e636082eb6c7821c51b7dd49ac1062e0d7 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 22 Mar 2013 18:06:11 +0100 Subject: [PATCH 027/213] New anvil icon (repair.svg), edited weapon.svg (added new gradient on dagger blade) and light source.svg (clear to see what happend). container icon is still work in progress. --- .../light source.svg | 136 +- .../referenceable record type/repair.svg | 1280 +++++++++++++++++ .../referenceable record type/weapon.svg | 37 +- 3 files changed, 1367 insertions(+), 86 deletions(-) create mode 100644 files/opencs/scalable/referenceable record type/repair.svg diff --git a/files/opencs/scalable/referenceable record type/light source.svg b/files/opencs/scalable/referenceable record type/light source.svg index 8575659f4..f8f506636 100644 --- a/files/opencs/scalable/referenceable record type/light source.svg +++ b/files/opencs/scalable/referenceable record type/light source.svg @@ -23,11 +23,11 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="5.12" - inkscape:cx="-14.844087" - inkscape:cy="12.523576" + inkscape:zoom="7.2407734" + inkscape:cx="15.039623" + inkscape:cy="28.976292" inkscape:document-units="px" - inkscape:current-layer="g4512" + inkscape:current-layer="g6692" showgrid="true" showguides="true" inkscape:guide-bbox="true" @@ -45,9 +45,9 @@ inkscape:object-paths="true" inkscape:snap-intersection-paths="true" inkscape:object-nodes="true" - inkscape:snap-global="true" + inkscape:snap-global="false" inkscape:snap-smooth-nodes="false" - inkscape:snap-grids="false" + inkscape:snap-grids="true" inkscape:snap-nodes="true"> + + + + + + + + + - - - @@ -1448,29 +1441,14 @@ - - + d="m 32.999997,6.5 a 6.4999967,2.5 0 1 1 -12.999994,0 6.4999967,2.5 0 1 1 12.999994,0 z" + transform="matrix(1.2476493,0,0,1.1773057,-95.452015,955.91965)" /> - + width="1.1570125" + height="2.2736316" + x="-62.967812" + y="961.29846" /> - + d="m -50.291451,955.99365 c -0.306142,0.58022 -0.173213,1.37959 -0.741985,1.81489 -0.555003,0.71326 -0.773186,1.6155 -1.259884,2.37061 -0.545654,1.01279 -0.9642,2.21153 -0.612129,3.35954 0.288553,1.36917 0.604843,2.81123 1.512357,3.91947 0.601372,0.6775 1.7644,0.89162 2.455823,0.22684 0.753966,-0.66641 1.219278,-1.61104 1.490732,-2.56706 0.268644,-1.09118 0.258571,-2.22309 0.405108,-3.33193 0.004,-0.92336 -0.539155,-1.718 -0.841509,-2.56039 -0.468277,-1.04235 -0.941776,-2.14938 -1.812123,-2.9223 -0.181111,-0.13328 -0.382557,-0.23957 -0.59639,-0.30967 z" + style="fill:#ffcb80;fill-opacity:1;stroke:none;filter:url(#filter4579)" + transform="matrix(1.1359383,0,0,1.1359383,-5.573807,-136.87442)" /> + d="m -50.089487,965.64147 c -0.06194,0.11739 -0.03504,0.2791 -0.150109,0.36717 -0.11228,0.14429 -0.15642,0.32682 -0.254882,0.47959 -0.110389,0.20489 -0.195064,0.4474 -0.123837,0.67965 0.05838,0.27699 0.122363,0.56873 0.305959,0.79293 0.121661,0.13707 0.356949,0.18038 0.496828,0.0459 0.152532,-0.13481 0.246667,-0.32592 0.301584,-0.51933 0.05435,-0.22075 0.05231,-0.44974 0.08196,-0.67406 8.27e-4,-0.18681 -0.109074,-0.34757 -0.170242,-0.51799 -0.09474,-0.21087 -0.190528,-0.43483 -0.366604,-0.5912 -0.03664,-0.0269 -0.07739,-0.0485 -0.120653,-0.0626 z" + style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter4575)" + transform="matrix(1.1359383,0,0,1.1359383,-5.573807,-136.87442)" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/weapon.svg b/files/opencs/scalable/referenceable record type/weapon.svg index 1e5aaac41..2e832fff7 100644 --- a/files/opencs/scalable/referenceable record type/weapon.svg +++ b/files/opencs/scalable/referenceable record type/weapon.svg @@ -23,9 +23,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="3.6203867" - inkscape:cx="-21.028476" - inkscape:cy="-1.6134251" + inkscape:zoom="5.12" + inkscape:cx="13.777504" + inkscape:cy="9.2319835" inkscape:document-units="px" inkscape:current-layer="g5966" showgrid="true" @@ -56,6 +56,17 @@ + + + + + @@ -1170,6 +1190,17 @@ d="m -69.333164,982.81214 0,3.65905 -6.823877,0 11.138217,11.04103 11.138216,-11.04103 -6.823877,0 0,-3.65905 -8.628679,0 z" id="path5146" inkscape:connector-curvature="0" /> + + + + From 001b56714a2da5efdbe940b5a06645a5fa863596 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 23 Mar 2013 16:16:23 +0100 Subject: [PATCH 028/213] Adding new status icons svg files. Qt svg does not allow blur to be used so I think that we should make png files of it but first information on the actual resolution needed is required... --- files/opencs/scalable/status/.directory | 5 + files/opencs/scalable/status/added.svg | 917 ++++++++++++++++ files/opencs/scalable/status/modified.svg | 1197 +++++++++++++++++++++ files/opencs/scalable/status/removed.svg | 1088 +++++++++++++++++++ 4 files changed, 3207 insertions(+) create mode 100644 files/opencs/scalable/status/.directory create mode 100644 files/opencs/scalable/status/added.svg create mode 100644 files/opencs/scalable/status/modified.svg create mode 100644 files/opencs/scalable/status/removed.svg diff --git a/files/opencs/scalable/status/.directory b/files/opencs/scalable/status/.directory new file mode 100644 index 000000000..e2d80ed58 --- /dev/null +++ b/files/opencs/scalable/status/.directory @@ -0,0 +1,5 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2013,3,21,10,19,49 +Version=3 +ViewMode=1 diff --git a/files/opencs/scalable/status/added.svg b/files/opencs/scalable/status/added.svg new file mode 100644 index 000000000..a5767d23b --- /dev/null +++ b/files/opencs/scalable/status/added.svg @@ -0,0 +1,917 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/files/opencs/scalable/status/modified.svg b/files/opencs/scalable/status/modified.svg new file mode 100644 index 000000000..c8b56cd04 --- /dev/null +++ b/files/opencs/scalable/status/modified.svg @@ -0,0 +1,1197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/files/opencs/scalable/status/removed.svg b/files/opencs/scalable/status/removed.svg new file mode 100644 index 000000000..719035be9 --- /dev/null +++ b/files/opencs/scalable/status/removed.svg @@ -0,0 +1,1088 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + From 43e863b0207396bf68ce868c11077cb7ba3f3b54 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 23 Mar 2013 16:22:17 +0100 Subject: [PATCH 029/213] Forgot to place the icons in the middle of the page. --- files/opencs/scalable/status/modified.svg | 67 ++----------------- files/opencs/scalable/status/removed.svg | 80 +++-------------------- 2 files changed, 13 insertions(+), 134 deletions(-) diff --git a/files/opencs/scalable/status/modified.svg b/files/opencs/scalable/status/modified.svg index c8b56cd04..3b183e314 100644 --- a/files/opencs/scalable/status/modified.svg +++ b/files/opencs/scalable/status/modified.svg @@ -24,8 +24,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.6203867" - inkscape:cx="-21.788854" - inkscape:cy="23.355872" + inkscape:cx="-39.987384" + inkscape:cy="43.542041" inkscape:document-units="px" inkscape:current-layer="g5966" showgrid="true" @@ -985,16 +985,6 @@ fx="-97.089668" fy="-33.913769" r="20" /> - - - - - - @@ -1140,7 +1083,7 @@ transform="matrix(0.97772023,0,0,0.97772023,100.68016,77.074325)"> - - - - - - - - + transform="matrix(0,1,-1,0,0.20564565,0.22375836)" /> + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:4.5731945;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + transform="matrix(0,1,-1,0,0.20564565,0.22375836)" /> From 59233e54b2083afd72d250928e7060de0d2a3419 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 23 Mar 2013 18:18:19 +0100 Subject: [PATCH 030/213] changing potion.svg according to pvdk sugestions --- .../referenceable record type/potion.svg | 162 +++++++++++------- 1 file changed, 104 insertions(+), 58 deletions(-) diff --git a/files/opencs/scalable/referenceable record type/potion.svg b/files/opencs/scalable/referenceable record type/potion.svg index 888006531..612f45aa4 100644 --- a/files/opencs/scalable/referenceable record type/potion.svg +++ b/files/opencs/scalable/referenceable record type/potion.svg @@ -24,10 +24,10 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="7.2407734" - inkscape:cx="18.842132" - inkscape:cy="26.695499" + inkscape:cx="3.6117613" + inkscape:cy="14.120537" inkscape:document-units="px" - inkscape:current-layer="g5966" + inkscape:current-layer="g3910" showgrid="true" showguides="true" inkscape:guide-bbox="true" @@ -55,6 +55,32 @@ + + + + + + + + + - + offset="0" + style="stop-color:#8cf0eb;stop-opacity:0.78431374;" /> @@ -930,22 +952,12 @@ fx="-150.6485" fy="-33.680485" r="19.749271" /> - + xlink:href="#linearGradient3853" + id="radialGradient3918" + cx="0.20415781" + cy="26.466549" + fx="0.20415781" + fy="26.466549" + r="15.52295" + gradientTransform="matrix(1.3421662,-1.1488417,0.96457332,1.1859542,-25.598784,-3.3438458)" + gradientUnits="userSpaceOnUse" /> + + + xlink:href="#linearGradient4535" + id="radialGradient4543" + cx="15.546875" + cy="24" + fx="15.546875" + fy="24" + r="15.52295" + gradientTransform="matrix(0.99999999,-0.04184496,0.06136199,1.5432733,-1.4726875,-12.388)" + gradientUnits="userSpaceOnUse" /> @@ -1017,30 +1047,46 @@ sodipodi:ry="4.4194174" d="m -133.13494,-22.158251 c 0,2.440777 -8.84205,4.419418 -19.74928,4.419418 -10.90722,0 -19.74927,-1.978641 -19.74927,-4.419418 0,-2.440777 8.84205,-4.419417 19.74927,-4.419417 10.90723,0 19.74928,1.97864 19.74928,4.419417 z" transform="matrix(0.92927807,0,0,1.0003876,63.663518,999.66077)" /> - + + + + + + - - Date: Sat, 23 Mar 2013 19:29:52 +0100 Subject: [PATCH 031/213] Drawer as container icon. Look a little better the old crappy chest but changes are needed. --- .../referenceable record type/container.svg | 1987 +++++++++-------- 1 file changed, 1108 insertions(+), 879 deletions(-) diff --git a/files/opencs/scalable/referenceable record type/container.svg b/files/opencs/scalable/referenceable record type/container.svg index 11ad79438..2a93954bd 100644 --- a/files/opencs/scalable/referenceable record type/container.svg +++ b/files/opencs/scalable/referenceable record type/container.svg @@ -23,9 +23,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="11.313709" - inkscape:cx="20.32374" - inkscape:cy="21.784699" + inkscape:zoom="8.0000004" + inkscape:cx="7.2255179" + inkscape:cy="2.9394873" inkscape:document-units="px" inkscape:current-layer="g9364" showgrid="true" @@ -43,1219 +43,1477 @@ inkscape:snap-bbox-edge-midpoints="false" inkscape:snap-bbox-midpoints="false" inkscape:object-paths="true" - inkscape:snap-intersection-paths="false" + inkscape:snap-intersection-paths="true" inkscape:object-nodes="true" inkscape:snap-global="true" - inkscape:snap-smooth-nodes="false" + inkscape:snap-smooth-nodes="true" inkscape:snap-grids="false" inkscape:snap-nodes="true" inkscape:snap-midpoints="false"> + type="xygrid" + id="grid3225" /> + + + + + id="linearGradient6181" + inkscape:collect="always"> + + + + + + + + + + + + + style="stop-color:#000000;stop-opacity:1;" /> + + + + + + + + + + + + + + + style="stop-color:#d07200;stop-opacity:1;" /> + + + + + style="stop-color:#000e50;stop-opacity:1;" /> + style="stop-color:#002bf4;stop-opacity:1;" /> + style="stop-color:#ffcb80;stop-opacity:1;" /> + style="stop-color:#000000;stop-opacity:1;" /> + id="stop8862" /> + id="stop8864" /> + id="stop8852" /> + style="stop-color:#ffffff;stop-opacity:1;" /> + id="stop8834" /> + id="stop8836" /> + id="stop4482" /> + id="stop4484" /> + inkscape:collect="always" + id="linearGradient3882"> + id="stop3884" /> + id="stop3886" /> + id="stop3941" /> + id="stop3943" /> + id="stop3881" /> + id="stop3883" /> + id="stop3869" /> + id="stop3871" /> + id="stop3855" /> + style="stop-color:#caf8db;stop-opacity:0.58823532;" /> + id="stop3857" /> + id="stop3847" /> + id="stop3849" /> + id="stop3839" /> + id="stop3841" /> + inkscape:collect="always" + id="linearGradient5958"> + id="stop5960" /> + id="stop5962" /> + id="stop5924" /> + id="stop5926" /> + style="stop-color:#000000;stop-opacity:1;" /> + id="stop6825" /> + style="stop-color:#3c3c3c;stop-opacity:0;" /> + style="stop-color:#204a87;stop-opacity:1;" /> + style="stop-color:#729fcf;stop-opacity:1;" /> + style="stop-color:#ffffff;stop-opacity:0.78431374;" /> + style="stop-color:#ffffff;stop-opacity:0;" /> + style="stop-color:#99bbd4;stop-opacity:1;" /> + style="stop-color:#5d93ba;stop-opacity:1;" /> + style="stop-color:#a6c4d9;stop-opacity:0.78431374;" /> + style="stop-color:#75a3c3;stop-opacity:1;" /> - + - - - - + + y1="936.95227" + x1="63.765881" + id="linearGradient3721" + xlink:href="#linearGradient3715" + inkscape:collect="always" /> + y1="948.8266" + x1="37.375645" + id="linearGradient3729" + xlink:href="#linearGradient3723" + inkscape:collect="always" /> - - + inkscape:collect="always" /> - - + id="linearGradient3737" + xlink:href="#linearGradient3707" + inkscape:collect="always" /> + id="linearGradient3739" + xlink:href="#linearGradient3723" + inkscape:collect="always" /> - + + + + + + + + + id="stop3820" /> + id="stop3822" /> + fx="-171.01654" + cy="123.88583" + cx="-171.01654" + gradientTransform="matrix(0.23290796,0.98292589,-1.5211573,0.36044393,244.44953,1091.8596)" + gradientUnits="userSpaceOnUse" + id="radialGradient5639" + xlink:href="#linearGradient3715-2" + inkscape:collect="always" /> + id="stop3717-4" /> + id="stop3719-9" /> + fx="-182.4375" + cy="116.19179" + cx="-182.4375" + gradientTransform="matrix(0.30667246,1.5835715,-1.396495,0.27044345,227.36718,1219.3395)" + gradientUnits="userSpaceOnUse" + id="radialGradient5641" + xlink:href="#linearGradient5299" + inkscape:collect="always" /> + id="stop5301" /> + id="stop5303" /> + fx="-172.875" + cy="119.59179" + cx="-172.875" + gradientTransform="matrix(1.0541003,0.65674043,-0.42405323,0.68062603,240.54684,45.0811)" + gradientUnits="userSpaceOnUse" + id="radialGradient6812" + xlink:href="#linearGradient3715-2" + inkscape:collect="always" /> - + + y1="941.44623" + x1="63.765881" + gradientTransform="matrix(0.37749331,0,0,0.37749331,-0.0711918,657.55701)" + gradientUnits="userSpaceOnUse" + id="linearGradient2843" + xlink:href="#linearGradient3715-6" + inkscape:collect="always" /> + style="stop-color:#99bbd4;stop-opacity:1;" /> + style="stop-color:#5d93ba;stop-opacity:1;" /> - + gradientTransform="matrix(-0.37749331,0,0,0.37749331,4.1838142,536.26868)" + x1="63.765881" + y1="941.44623" + x2="63.765881" + y2="965.56183" /> + + y2="37.613949" + x2="26.643335" + y1="39.630547" + x1="27.183681" + id="linearGradient6823-6" + xlink:href="#linearGradient6815-6" + inkscape:collect="always" /> + style="stop-color:#000000;stop-opacity:1;" /> + id="stop6825-9" /> + style="stop-color:#3c3c3c;stop-opacity:0;" /> + fx="-172.875" + cy="119.59179" + cx="-172.875" + gradientTransform="matrix(1.0541003,0.65674043,-0.42405323,0.68062603,158.26577,1130.8958)" + gradientUnits="userSpaceOnUse" + id="radialGradient5639-0" + xlink:href="#linearGradient3715-2-4" + inkscape:collect="always" /> + id="stop3717-4-8" /> + id="stop3719-9-7" /> + fx="-182.4375" + cy="116.19179" + cx="-182.4375" + gradientTransform="matrix(0.30667246,1.5835715,-1.396495,0.27044345,218.94267,1272.3725)" + gradientUnits="userSpaceOnUse" + id="radialGradient5641-1" + xlink:href="#linearGradient5299-7" + inkscape:collect="always" /> + id="stop5301-2" /> + id="stop5303-7" /> - - + spreadMethod="reflect" /> + + + id="radialGradient3843" + cx="-97.089668" + cy="-33.913769" + fx="-97.089668" + fy="-33.913769" + r="20" + gradientTransform="matrix(-0.03337852,1.2984223,-1.7840914,0.11666088,-155.09309,1098.8832)" + gradientUnits="userSpaceOnUse" /> + id="radialGradient3851" + cx="34.5625" + cy="54.418995" + fx="34.5625" + fy="54.418995" + r="13.49375" + gradientTransform="matrix(1.3458814,-1.3743665,1.2334026,1.233403,-192.05563,977.88376)" + gradientUnits="userSpaceOnUse" /> - + gradientTransform="translate(44.104424,-40.169184)" /> + + id="radialGradient3875" + cx="-150.6485" + cy="-33.680485" + fx="-150.6485" + fy="-33.680485" + r="19.749271" + gradientTransform="matrix(0.99999984,-2.6136065e-7,1.3555931e-7,0.44755236,-2.2357346,-2.665094)" + gradientUnits="userSpaceOnUse" /> - - - - - + gradientUnits="userSpaceOnUse" /> - - - + - - - - - + r="3.4179688" /> - - + + + id="radialGradient3905" + gradientUnits="userSpaceOnUse" + cx="30.273438" + cy="53.175781" + fx="30.273438" + fy="53.175781" + r="3.4179688" /> + + + + + gradientTransform="translate(0.20586672,1.984673e-5)" /> + + + id="radialGradient3951" + gradientUnits="userSpaceOnUse" + cx="30.273438" + cy="53.175781" + fx="30.273438" + fy="53.175781" + r="3.4179688" /> + + + + + + id="radialGradient3963" + gradientUnits="userSpaceOnUse" + cx="30.273438" + cy="53.175781" + fx="30.273438" + fy="53.175781" + r="3.4179688" /> + - + + id="linearGradient4486" + x1="-152.88422" + y1="-17.455395" + x2="-152.88422" + y2="-41.022785" + gradientUnits="userSpaceOnUse" /> - + - + - + gradientTransform="matrix(0.99999984,-2.6136065e-7,1.3555931e-7,0.44755236,-2.2357346,-2.665094)" + cx="-150.6485" + cy="-33.680485" + fx="-150.6485" + fy="-33.680485" + r="19.749271" /> + - + gradientTransform="matrix(0.91762814,0,0,1.0003875,-5.0078269,1004.2961)" + spreadMethod="reflect" + x1="-72.843758" + y1="-45.656265" + x2="-72.843758" + y2="-45.944225" /> + + id="radialGradient5618" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.03337852,1.2984223,-1.7840914,0.11666088,-155.09309,1098.8832)" + cx="-97.089668" + cy="-33.913769" + fx="-97.089668" + fy="-33.913769" + r="20" /> + id="stop4678" /> + id="stop4680" /> + id="stop4693" /> + id="stop4695" /> + id="stop4715" /> + style="stop-color:#707070;stop-opacity:0;" /> + id="stop4717" /> + id="stop4725" /> + id="stop4727" /> + id="stop4655" /> + id="stop4657" /> + y2="1093.0337" + x2="186.81903" + y1="1139.3492" + x1="203.09436" + id="linearGradient9295" + xlink:href="#linearGradient9289" + inkscape:collect="always" /> + x2="127.51315" + y1="1154.9745" + x1="124.46073" + id="linearGradient9311" + xlink:href="#linearGradient9305" + inkscape:collect="always" /> + + id="linearGradient9315" + xlink:href="#linearGradient8832" + inkscape:collect="always" /> + + + + + y1="1219.9902" + x1="143.30029" + gradientUnits="userSpaceOnUse" + id="linearGradient9359" + xlink:href="#linearGradient8832" + inkscape:collect="always" /> + + id="linearGradient6042" + xlink:href="#linearGradient6034" + inkscape:collect="always" /> + + + + + id="linearGradient4261" + xlink:href="#linearGradient6034" + inkscape:collect="always" /> + y2="40.483025" + x2="5.8733339" + y1="42.337013" + x1="5.8733339" + id="linearGradient5031" + xlink:href="#linearGradient5025" + inkscape:collect="always" /> + y2="26.024555" + x2="16.901522" + y1="25.302221" + x1="15.650404" + id="linearGradient5041" + xlink:href="#linearGradient5025" + inkscape:collect="always" /> + y2="25.241705" + x2="34.729317" + y1="26.024555" + x1="33.373379" + id="linearGradient5049" + xlink:href="#linearGradient5025" + inkscape:collect="always" /> + y2="21.523092" + x2="16.90152" + y1="23.258371" + x1="16.90152" + id="linearGradient5057" + xlink:href="#linearGradient5025" + inkscape:collect="always" /> + y2="24.861507" + x2="15.974848" + y1="28.879158" + x1="5.8733373" + id="linearGradient5095" + xlink:href="#linearGradient5089" + inkscape:collect="always" /> + y2="24.798422" + x2="34.262527" + y1="29.089437" + x1="44.388447" + id="linearGradient5105" + xlink:href="#linearGradient5099" + inkscape:collect="always" /> + y2="16.485245" + x2="33.37338" + y1="16.485245" + x1="16.901521" + id="linearGradient6115" + xlink:href="#linearGradient6109" + inkscape:collect="always" /> + id="linearGradient6157" + xlink:href="#linearGradient5025" + inkscape:collect="always" /> + id="linearGradient6159" + xlink:href="#linearGradient5025" + inkscape:collect="always" /> + id="linearGradient6161" + xlink:href="#linearGradient5025" + inkscape:collect="always" /> + gradientUnits="userSpaceOnUse" + y2="1074.7314" + x2="227.6591" + y1="1120.4557" + x1="227.6591" + id="linearGradient6171" + xlink:href="#linearGradient6165" + inkscape:collect="always" /> + + + + + + + + + + + + + + + + + @@ -1270,90 +1528,61 @@ + inkscape:groupmode="layer" + inkscape:label="Livello 1"> + transform="matrix(0.29626046,0,0,0.29626046,-45.835699,695.27639)" + id="g8044"> - + transform="translate(1.4700294,-5.8981036)" + id="g9364"> - - - - - - - - + transform="translate(98.027824,-15.186023)" /> + + id="path4273" + d="m 206.47648,1074.7314 55.59925,0 0,45.7242 -55.59925,10e-5 0,-45.7243" + style="fill:url(#linearGradient6171-857-364-729);fill-opacity:1;stroke:#303030;stroke-opacity:1;stroke-width:1.01262247;stroke-miterlimit:4;stroke-dasharray:none" /> + - + id="path4275" + d="m 169.25186,1139.4281 130.00422,0 -10e-6,45.4257 -130.00422,0 z" + style="fill:url(#linearGradient6157);fill-opacity:1;stroke:#232323;stroke-opacity:1;stroke-width:1.01262247;stroke-miterlimit:4;stroke-dasharray:none" /> + transform="matrix(3.3754082,0,0,3.3754082,146.59884,1045.162)" + d="m 29.499998,34.65625 c 0,1.950255 -1.580995,3.53125 -3.53125,3.53125 -1.950255,0 -3.53125,-1.580995 -3.53125,-3.53125 0,-1.950255 1.580995,-3.53125 3.53125,-3.53125 1.950255,0 3.53125,1.580995 3.53125,3.53125 z" + sodipodi:ry="3.5312498" + sodipodi:rx="3.5312498" + sodipodi:cy="34.65625" + sodipodi:cx="25.968748" + id="path6147" + style="fill:url(#radialGradient6179);fill-opacity:1;stroke:url(#radialGradient6187);stroke-opacity:1" + sodipodi:type="arc" /> + id="g9321" /> From e97319c0bba33b551861183a0d5f0d799f2b978f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 23 Mar 2013 19:32:37 +0100 Subject: [PATCH 032/213] Drawer as container icon looks actually quite good IMHO. --- .../referenceable record type/container.svg | 183 +++++++++++++----- 1 file changed, 134 insertions(+), 49 deletions(-) diff --git a/files/opencs/scalable/referenceable record type/container.svg b/files/opencs/scalable/referenceable record type/container.svg index 2a93954bd..6c4973708 100644 --- a/files/opencs/scalable/referenceable record type/container.svg +++ b/files/opencs/scalable/referenceable record type/container.svg @@ -23,11 +23,11 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="8.0000004" - inkscape:cx="7.2255179" - inkscape:cy="2.9394873" + inkscape:zoom="5.6568545" + inkscape:cx="-6.640249" + inkscape:cy="16.907775" inkscape:document-units="px" - inkscape:current-layer="g9364" + inkscape:current-layer="g8044" showgrid="true" showguides="true" inkscape:guide-bbox="true" @@ -45,7 +45,7 @@ inkscape:object-paths="true" inkscape:snap-intersection-paths="true" inkscape:object-nodes="true" - inkscape:snap-global="true" + inkscape:snap-global="false" inkscape:snap-smooth-nodes="true" inkscape:snap-grids="false" inkscape:snap-nodes="true" @@ -72,6 +72,18 @@ + + + + @@ -1502,7 +1514,8 @@ x1="227.6591" id="linearGradient6171-857-364-729" xlink:href="#linearGradient6165-696-389-794" - inkscape:collect="always" /> + inkscape:collect="always" + gradientTransform="matrix(0.87072097,0,0,1.0005854,30.284126,-0.66139717)" /> + + + + + + + @@ -1536,49 +1620,50 @@ transform="matrix(0.29626046,0,0,0.29626046,-45.835699,695.27639)" id="g8044"> - - - - - - - - + transform="translate(99.497853,-21.084127)" + style="fill:#ff0000;fill-opacity:1;stroke:none" + id="g3951" /> + + + + + + + Date: Sat, 23 Mar 2013 19:53:10 +0100 Subject: [PATCH 033/213] Update the status icons. X as removed.svg and backgrounds for status icons stolen from oxygen emblems :P It gives clear look for it. --- files/opencs/scalable/status/added.svg | 60 +- files/opencs/scalable/status/modified.svg | 60 +- files/opencs/scalable/status/removed.svg | 985 ++++++++++------------ 3 files changed, 577 insertions(+), 528 deletions(-) diff --git a/files/opencs/scalable/status/added.svg b/files/opencs/scalable/status/added.svg index a5767d23b..e0af57002 100644 --- a/files/opencs/scalable/status/added.svg +++ b/files/opencs/scalable/status/added.svg @@ -23,9 +23,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="2.8284271" - inkscape:cx="6.6635778" - inkscape:cy="31.541579" + inkscape:zoom="5.6568542" + inkscape:cx="27.462558" + inkscape:cy="10.232345" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" @@ -878,6 +878,29 @@ stdDeviation="57.354192" id="feGaussianBlur4632" /> + + + + + @@ -896,6 +919,35 @@ id="layer1" inkscape:groupmode="layer" inkscape:label="Livello 1"> + + + + + + + + + + + + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-linejoin:round" /> + + + + + @@ -1081,6 +1104,35 @@ + + + + + + + + + + + - - + inkscape:snap-nodes="true" /> + id="linearGradient3902" + inkscape:collect="always"> - - - - - - - - - - - - - - - - - - - - - - - - - + style="stop-color:#000000;stop-opacity:1;" /> + style="stop-color:#000000;stop-opacity:0;" /> + id="linearGradient3886" + inkscape:collect="always"> + style="stop-color:#fff226;stop-opacity:1;" /> + style="stop-color:#fff226;stop-opacity:0;" /> + id="linearGradient9248"> + style="stop-color:#ffffff;stop-opacity:1;" /> + style="stop-color:#b4b4b4;stop-opacity:1;" /> + id="linearGradient8521"> - + style="stop-color:#00105d;stop-opacity:1;" /> + style="stop-color:#00105d;stop-opacity:0;" /> + id="linearGradient7487"> + id="stop7489" /> - - - - - - - - + id="stop7491" /> + id="linearGradient6034"> + id="stop6036" /> + id="stop6038" /> @@ -443,17 +343,6 @@ offset="1" id="stop3822" /> - - - - - - - + id="linearGradient3955-87-471"> + + + + + + + + + + - - - - - - - - - - - - + gradientTransform="translate(-5.8907179,205.15612)" /> + gradientTransform="matrix(1,0,0,0.60717495,0,6.6355278)" + r="3.1054714" + fy="16.891813" + fx="29.111721" + cy="16.891813" + cx="29.111721" + id="radialGradient3892" + xlink:href="#linearGradient3886" + inkscape:collect="always" /> + gradientTransform="matrix(2.1494315,0.36121083,-0.30519899,1.8161266,2.9871553,-34.404392)" + r="15.46875" + fy="32.971859" + fx="13.599908" + cy="32.971859" + cx="13.599908" + id="radialGradient3908" + xlink:href="#linearGradient3902" + inkscape:collect="always" /> + + + + + + + + + gradientTransform="matrix(1,0,0,1.0000234,0,-0.00345228)" + cx="237.35278" + cy="147.22479" + fx="237.35278" + fy="147.22479" + r="107.16857" /> - + id="linearGradient3880"> + + + + gradientTransform="matrix(0.43641683,0,0,0.43645606,205.85223,33.676924)" + cx="72.191498" + cy="260.15875" + fx="72.191498" + fy="260.15875" + r="149.18433" /> + + + + + gradientTransform="matrix(1,0,0,1.0000234,0,-0.00611206)" + cx="83.637177" + cy="260.86032" + fx="83.637177" + fy="260.86032" + r="107.16857" /> + + + + + gradientTransform="matrix(0.43641683,0,0,0.43645606,52.136611,147.31246)" + cx="72.191498" + cy="260.15875" + fx="72.191498" + fy="260.15875" + r="149.18433" /> + + + + + gradientTransform="matrix(1,0,0,1.0000234,0,-0.00345228)" + cx="237.35278" + cy="147.22479" + fx="237.35278" + fy="147.22479" + r="107.16857" /> + + + + + gradientTransform="matrix(0.43641683,0,0,0.43645606,205.85223,33.676924)" + cx="72.191498" + cy="260.15875" + fx="72.191498" + fy="260.15875" + r="149.18433" /> + + + + + xlink:href="#linearGradient3880" + id="radialGradient3888" + cx="237.35278" + cy="147.22479" + fx="237.35278" + fy="147.22479" + r="107.16857" + gradientTransform="matrix(1,0,0,1.0000234,0,-0.00345228)" + gradientUnits="userSpaceOnUse" /> + + + + + gradientTransform="matrix(0.43641683,0,0,0.43645606,205.85223,33.676924)" + cx="72.191498" + cy="260.15875" + fx="72.191498" + fy="260.15875" + r="149.18433" /> + + + + + xlink:href="#linearGradient3880" + id="radialGradient3886" + cx="83.637177" + cy="260.86032" + fx="83.637177" + fy="260.86032" + r="107.16857" + gradientTransform="matrix(1,0,0,1.0000234,0,-0.00611206)" + gradientUnits="userSpaceOnUse" /> + + + + + gradientTransform="matrix(0.43641683,0,0,0.43645606,52.136611,147.31246)" + cx="72.191498" + cy="260.15875" + fx="72.191498" + fy="260.15875" + r="149.18433" /> + + + + - + id="radialGradient3964" + xlink:href="#linearGradient3846" + inkscape:collect="always" /> + id="filter4622"> + stdDeviation="57.354192" + id="feGaussianBlur4624" /> + id="filter4630"> + stdDeviation="57.354192" + id="feGaussianBlur4632" /> + + + + + @@ -989,36 +920,50 @@ inkscape:groupmode="layer" inkscape:label="Livello 1"> + id="g6138" + transform="translate(3.5529905,1004.1857)"> - - - + transform="matrix(3.2000002,0,0,3.2000002,101.31818,-39.364891)" + id="g6116"> + + + + + + + + + + From b7f95cd271b522f28d4dcf86799648ecd43e785f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 24 Mar 2013 10:19:46 +0100 Subject: [PATCH 034/213] Random item (dice). Container.svg needs to be scraped, I'm afraid. --- .../referenceable record type/container.svg | 2358 +++++++++-------- .../referenceable record type/potion.svg | 107 +- .../referenceable record type/random item.svg | 1462 ++++++++++ 3 files changed, 2839 insertions(+), 1088 deletions(-) create mode 100644 files/opencs/scalable/referenceable record type/random item.svg diff --git a/files/opencs/scalable/referenceable record type/container.svg b/files/opencs/scalable/referenceable record type/container.svg index 6c4973708..8c9465b66 100644 --- a/files/opencs/scalable/referenceable record type/container.svg +++ b/files/opencs/scalable/referenceable record type/container.svg @@ -23,11 +23,11 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="5.6568545" - inkscape:cx="-6.640249" - inkscape:cy="16.907775" + inkscape:zoom="11.313709" + inkscape:cx="13.572484" + inkscape:cy="13.658831" inkscape:document-units="px" - inkscape:current-layer="g8044" + inkscape:current-layer="g3302" showgrid="true" showguides="true" inkscape:guide-bbox="true" @@ -51,1553 +51,1721 @@ inkscape:snap-nodes="true" inkscape:snap-midpoints="false"> + id="grid3225" + type="xygrid" /> + id="guide5067" /> + id="guide5069" /> + id="guide5071" /> + id="guide5073" /> + id="linearGradient4932"> + + + + + + + + + + style="stop-color:#000000;stop-opacity:1;" /> + + style="stop-color:#000000;stop-opacity:1;" /> + + + + + style="stop-color:#eeeeee;stop-opacity:1;" /> + style="stop-color:#e1fbfa;stop-opacity:1;" /> + id="linearGradient4843"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + id="stop6167" /> + id="stop6169" /> + id="stop6111" /> + style="stop-color:#000000;stop-opacity:0;" /> + id="stop6113" /> + id="stop5101" /> + id="stop5103" /> + id="stop5091" /> + id="stop5093" /> + id="stop5027" /> + style="stop-color:#502c00;stop-opacity:1;" /> + id="stop5029" /> + id="stop3976" /> + id="stop3978" /> + id="stop9307" /> + id="stop9309" /> + id="stop9291" /> + id="stop9293" /> + style="stop-color:#ff0000;stop-opacity:1;" /> + style="stop-color:#ff0000;stop-opacity:0;" /> + style="stop-color:#b3bbad;stop-opacity:1;" /> + id="stop8858" /> + style="stop-color:#d07200;stop-opacity:1;" /> + style="stop-color:#965200;stop-opacity:1;" /> + style="stop-color:#000000;stop-opacity:0;" /> + style="stop-color:#000000;stop-opacity:1;" /> + id="linearGradient3882" + inkscape:collect="always"> + style="stop-color:#000000;stop-opacity:1;" /> + style="stop-color:#000000;stop-opacity:0;" /> + style="stop-color:#000000;stop-opacity:0.784" /> + style="stop-color:#000000;stop-opacity:0;" /> + style="stop-color:#ffffff;stop-opacity:0.78431374;" /> + style="stop-color:#b4b4b4;stop-opacity:0.72549021;" /> + style="stop-color:#5a0048;stop-opacity:1;" /> + style="stop-color:#960078;stop-opacity:1;" /> + style="stop-color:#caf8f6;stop-opacity:0.39215687;" /> + id="stop3861" /> + style="stop-color:#caf8f6;stop-opacity:0.39215687;" /> + style="stop-color:#aa0088;stop-opacity:1;" /> + style="stop-color:#fa00c8;stop-opacity:1;" /> + style="stop-color:#ffffff;stop-opacity:0.78431374;" /> + style="stop-color:#caf8f6;stop-opacity:0;" /> + id="linearGradient5958" + inkscape:collect="always"> + style="stop-color:#caf8f6;stop-opacity:1;" /> + style="stop-color:#caf8f6;stop-opacity:0;" /> + style="stop-color:#c84900;stop-opacity:1;" /> + style="stop-color:#c84900;stop-opacity:0.19607843;" /> + id="stop6817" /> + style="stop-color:#3c3c3c;stop-opacity:0.58823532;" /> + id="stop6819" /> + id="stop4024" /> + id="stop4026" /> + id="stop3725" /> + id="stop3727" /> + id="stop3717" /> + id="stop3719" /> + id="stop3709" /> + id="stop3711" /> - + + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> - - - + gradientTransform="translate(0.2341189,5.74082)" /> + gradientTransform="translate(0.2341196,6.0908086)" /> + gradientTransform="translate(0.2341189,5.74082)" /> + gradientTransform="translate(0.2341196,6.0908086)" + x1="63.765881" + y1="936.95227" + x2="63.765881" + y2="983.41931" /> - - + y2="1029.8864" /> + + id="linearGradient3742" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0066488,0,0,1.0066488,0.21965498,-1.1089658)" + x1="63.765881" + y1="949.3266" + x2="63.765881" + y2="1029.8864" /> + + gradientTransform="matrix(1.0066488,0,0,1.0066488,0.21965567,-0.75665045)" + x1="63.765881" + y1="936.95227" + x2="63.765881" + y2="983.41931" /> + gradientTransform="matrix(1.0066488,0,0,1.0066488,0.21965567,-0.75665045)" + x1="63.765881" + y1="936.95227" + x2="63.765881" + y2="983.41931" /> + + + gradientTransform="matrix(0.91716429,0,0,0.91716429,2.2512556,85.18512)" /> + + style="stop-color:#1e1e1e;stop-opacity:1;" /> + style="stop-color:#000000;stop-opacity:0;" /> + id="radialGradient5639" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.23290796,0.98292589,-1.5211573,0.36044393,244.44953,1091.8596)" + cx="-171.01654" + cy="123.88583" + fx="-171.01654" + fy="123.88583" + r="29.000444" /> + style="stop-color:#ffffff;stop-opacity:1;" /> + style="stop-color:#b3bbad;stop-opacity:1;" /> + id="radialGradient5641" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.30667246,1.5835715,-1.396495,0.27044345,227.36718,1219.3395)" + cx="-182.4375" + cy="116.19179" + fx="-182.4375" + fy="116.19179" + r="28.421875" /> + style="stop-color:#000e50;stop-opacity:1;" /> + style="stop-color:#000000;stop-opacity:1;" /> - + + xlink:href="#linearGradient6815" + id="linearGradient6823" + x1="27.183681" + y1="39.630547" + x2="26.643335" + y2="37.613949" + gradientUnits="userSpaceOnUse" /> + id="linearGradient2843" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.37749331,0,0,0.37749331,-0.0711918,657.55701)" + x1="63.765881" + y1="941.44623" + x2="63.765881" + y2="965.56183" /> + id="stop3717-6" /> + id="stop3719-4" /> - + x1="63.765881" + gradientTransform="matrix(-0.37749331,0,0,0.37749331,4.1838142,536.26868)" + gradientUnits="userSpaceOnUse" + id="linearGradient3184" + xlink:href="#linearGradient3715-6" + inkscape:collect="always" /> + + id="stop6817-4" /> + style="stop-color:#3c3c3c;stop-opacity:0.58823532;" /> + id="stop6819-5" /> + id="radialGradient5639-0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0541003,0.65674043,-0.42405323,0.68062603,158.26577,1130.8958)" + cx="-172.875" + cy="119.59179" + fx="-172.875" + fy="119.59179" + r="29.000444" /> + style="stop-color:#ffffff;stop-opacity:1;" /> + style="stop-color:#b3bbad;stop-opacity:1;" /> + id="radialGradient5641-1" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.30667246,1.5835715,-1.396495,0.27044345,218.94267,1272.3725)" + cx="-182.4375" + cy="116.19179" + fx="-182.4375" + fy="116.19179" + r="28.421875" /> + style="stop-color:#000e50;stop-opacity:1;" /> + style="stop-color:#000000;stop-opacity:1;" /> + id="radialGradient3063" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.30667246,1.5835715,-1.396495,0.27044345,136.6616,1353.825)" + cx="-182.4375" + cy="116.19179" + fx="-182.4375" + fy="116.19179" + r="28.421875" /> + y2="-45.944225" + x2="-72.843758" + y1="-45.656265" + x1="-72.843758" + id="linearGradient5928" + xlink:href="#linearGradient5922" + inkscape:collect="always" /> + r="20.15" + fy="-39.275696" + fx="-103.70541" + cy="-39.275696" + cx="-103.70541" + id="radialGradient5964" + xlink:href="#linearGradient5958" + inkscape:collect="always" /> + x2="-72.843758" + y1="-45.656265" + x1="-72.843758" + spreadMethod="reflect" + gradientUnits="userSpaceOnUse" + id="linearGradient5973" + xlink:href="#linearGradient5922" + inkscape:collect="always" /> + r="20" + fy="-33.913769" + fx="-97.089668" + cy="-33.913769" + cx="-97.089668" + id="radialGradient3843" + xlink:href="#linearGradient3837" + inkscape:collect="always" /> + r="13.49375" + fy="54.418995" + fx="34.5625" + cy="54.418995" + cx="34.5625" + id="radialGradient3851" + xlink:href="#linearGradient3867" + inkscape:collect="always" /> + y2="1017.9076" + x2="-104.17097" + y1="1017.7004" + x1="-140.89291" + id="linearGradient3859" + xlink:href="#linearGradient3853" + inkscape:collect="always" /> + fx="-116.29909" + cy="-37.504356" + cx="-116.29909" + gradientTransform="matrix(-0.00108712,0.18221846,-0.82985011,4.6460161e-7,-113.08325,972.23283)" + gradientUnits="userSpaceOnUse" + id="radialGradient3865" + xlink:href="#linearGradient3837" + inkscape:collect="always" /> - + r="19.749271" + fy="-33.680485" + fx="-150.6485" + cy="-33.680485" + cx="-150.6485" + id="radialGradient3875" + xlink:href="#linearGradient3845" + inkscape:collect="always" /> - - - - + inkscape:collect="always" /> - - - - - + inkscape:collect="always" /> - - - - - + inkscape:collect="always" /> + + + + + + fx="30.273438" + cy="53.175781" + cx="30.273438" + gradientUnits="userSpaceOnUse" + id="radialGradient3917" + xlink:href="#linearGradient3879" + inkscape:collect="always" /> + + + + + + fx="30.273438" + cy="53.175781" + cx="30.273438" + gradientUnits="userSpaceOnUse" + id="radialGradient3953" + xlink:href="#linearGradient3879" + inkscape:collect="always" /> + + + + + + fx="30.273438" + cy="53.175781" + cx="30.273438" + gradientUnits="userSpaceOnUse" + id="radialGradient3965" + xlink:href="#linearGradient3879" + inkscape:collect="always" /> + gradientTransform="matrix(0.13602194,8.9478727e-7,-2.3305974e-7,0.03057111,-132.08862,-21.48071)" + r="19.749271" + fy="-22.158251" + fx="-152.88422" + cy="-22.158251" + cx="-152.88422" + id="radialGradient3888" + xlink:href="#linearGradient3882" + inkscape:collect="always" /> + x2="-152.88422" + y1="-17.455395" + x1="-152.88422" + id="linearGradient4486" + xlink:href="#linearGradient4480" + inkscape:collect="always" /> - + - + - + id="radialGradient5610" + xlink:href="#linearGradient3845" + inkscape:collect="always" /> + - + id="linearGradient5614" + xlink:href="#linearGradient5922" + inkscape:collect="always" /> + + fx="-97.089668" + cy="-33.913769" + cx="-97.089668" + gradientTransform="matrix(-0.03337852,1.2984223,-1.7840914,0.11666088,-155.09309,1098.8832)" + gradientUnits="userSpaceOnUse" + id="radialGradient5618" + xlink:href="#linearGradient3837" + inkscape:collect="always" /> + style="stop-color:#d07200;stop-opacity:1;" /> + style="stop-color:#603500;stop-opacity:1;" /> + style="stop-color:#ffffff;stop-opacity:1;" /> + style="stop-color:#cccccc;stop-opacity:0;" /> + style="stop-color:#000000;stop-opacity:1" /> + id="stop4721" /> + style="stop-color:#000000;stop-opacity:1;" /> + style="stop-color:#969696;stop-opacity:1;" /> + style="stop-color:#cccccc;stop-opacity:1;" /> + style="stop-color:#fa00c8;stop-opacity:1;" /> + style="stop-color:#aa0088;stop-opacity:1;" /> - + + id="linearGradient9311" + x1="124.46073" + y1="1154.9745" + x2="127.51315" + y2="1151.9221" + gradientUnits="userSpaceOnUse" /> - + x1="199.76904" + y1="110.00295" + x2="236.769" + y2="78.409447" /> + x1="143.30029" + y1="1219.9902" + x2="72.589622" + y2="1149.2795" /> + x1="158.40988" + y1="1098.7366" + x2="147.26907" + y2="1109.0519" /> + x1="235.71814" + y1="1196.6267" + x2="292.90564" + y2="1135.908" + gradientTransform="translate(5.6098624,8.1772778)" /> + x1="199.76904" + y1="110.00295" + x2="236.769" + y2="78.409447" /> + x1="124.46073" + y1="1154.9745" + x2="127.51315" + y2="1151.9221" /> + x1="143.30029" + y1="1219.9902" + x2="72.589622" + y2="1149.2795" /> + + id="linearGradient6042" + gradientUnits="userSpaceOnUse" + x1="-2256.6802" + y1="1067.036" + x2="37.487514" + y2="2532.4438" + gradientTransform="translate(-1.6900304,-354.84909)" /> + id="stop6036" /> + id="stop6038" /> - + gradientTransform="matrix(0.05826577,0,0,0.05826577,458.90519,929.78821)" + x1="-2256.6802" + y1="1067.036" + x2="37.487514" + y2="2532.4438" /> - + spreadMethod="reflect" /> + id="linearGradient5041" + x1="15.650404" + y1="25.302221" + x2="16.901522" + y2="26.024555" + gradientUnits="userSpaceOnUse" + spreadMethod="reflect" /> + spreadMethod="reflect" /> + + + id="linearGradient5105" + x1="44.388447" + y1="29.089437" + x2="34.262527" + y2="24.798422" + gradientUnits="userSpaceOnUse" /> - + gradientTransform="matrix(3.3754082,0,0,3.3754082,149.42695,1041.9491)" /> - + + id="linearGradient6159" + gradientUnits="userSpaceOnUse" + spreadMethod="reflect" + x1="33.373379" + y1="26.024555" + x2="34.729317" + y2="25.241705" + gradientTransform="matrix(3.3754082,0,0,3.3754082,149.42695,1041.9491)" /> + + id="linearGradient6171" + x1="227.6591" + y1="1120.4557" + x2="227.6591" + y2="1074.7314" + gradientUnits="userSpaceOnUse" /> - + + id="radialGradient6187" + cx="25.968748" + cy="34.65625" + fx="25.968748" + fy="34.65625" + r="4.0312498" + gradientUnits="userSpaceOnUse" /> + id="linearGradient6171-857" + x1="227.6591" + y1="1120.4557" + x2="227.6591" + y2="1074.7314" + gradientUnits="userSpaceOnUse" /> + id="stop6426" /> + id="stop6428" /> + id="linearGradient6171-857-364" + x1="227.6591" + y1="1120.4557" + x2="227.6591" + y2="1074.7314" + gradientUnits="userSpaceOnUse" /> + id="stop6916" /> + id="stop6918" /> + xlink:href="#linearGradient6165-696-389-794" + id="linearGradient6171-857-364-729" + x1="227.6591" + y1="1120.4557" + x2="227.6591" + y2="1074.7314" + gradientUnits="userSpaceOnUse" /> + id="stop7414" /> + id="stop7416" /> + x2="223.25838" + y1="1184.9249" + x1="223.25838" + id="linearGradient7695" + xlink:href="#linearGradient7689" + inkscape:collect="always" /> + - + - + + id="linearGradient4906" + xlink:href="#linearGradient4853" + inkscape:collect="always" /> + id="linearGradient4908" + xlink:href="#linearGradient4853" + inkscape:collect="always" /> + id="linearGradient4910" + xlink:href="#linearGradient4885" + inkscape:collect="always" /> + id="linearGradient4912" + xlink:href="#linearGradient4885" + inkscape:collect="always" /> + + + + + + + + @@ -1612,62 +1780,120 @@ + id="layer1" + transform="translate(0,-1004.3622)"> + id="g8044" + transform="matrix(0.29626046,0,0,0.29626046,-45.835699,695.27639)"> - - - - - - - + transform="translate(99.497853,-21.084127)" /> + transform="translate(156.56239,-59.761743)" /> + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/potion.svg b/files/opencs/scalable/referenceable record type/potion.svg index 612f45aa4..552c14f19 100644 --- a/files/opencs/scalable/referenceable record type/potion.svg +++ b/files/opencs/scalable/referenceable record type/potion.svg @@ -23,9 +23,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="7.2407734" - inkscape:cx="3.6117613" - inkscape:cy="14.120537" + inkscape:zoom="5.12" + inkscape:cx="-13.774317" + inkscape:cy="16.062941" inkscape:document-units="px" inkscape:current-layer="g3910" showgrid="true" @@ -41,7 +41,7 @@ inkscape:bbox-paths="true" inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="true" - inkscape:snap-bbox-midpoints="true" + inkscape:snap-bbox-midpoints="false" inkscape:object-paths="true" inkscape:snap-intersection-paths="false" inkscape:object-nodes="false" @@ -55,6 +55,21 @@ + + + + + + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2031694,0,0,1.0551213,-87.506267,947.79452)" /> + + + + + @@ -1067,26 +1130,26 @@ d="m -133.13494,-22.158251 c 0,2.440777 -8.84205,4.419418 -19.74928,4.419418 -10.90722,0 -19.74927,-1.978641 -19.74927,-4.419418 0,-2.440777 8.84205,-4.419417 19.74927,-4.419417 10.90723,0 19.74928,1.97864 19.74928,4.419417 z" transform="matrix(0.33492065,0,0,0.3605492,-27.223425,956.85737)" /> + style="opacity:0.75;fill:url(#linearGradient3148);fill-opacity:1;stroke:#7d7d7d;stroke-width:0.43104154;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m -84.982974,948.64215 c -0.64997,0.0595 -1.165571,0.65963 -1.165571,1.38485 l 0,2.6378 c 0,0.7229 0.518091,1.32155 1.165571,1.38485 l 0,0.46162 c 0.544843,-0.74781 3.244284,-1.3189 6.504634,-1.3189 3.36081,0 6.119682,0.60297 6.542234,1.38484 l 0.0752,0 0,-0.52756 c 0.64747,-0.063 1.16557,-0.66195 1.16557,-1.38485 l 0,-2.6378 c 0,-0.73861 -0.535775,-1.34418 -1.203169,-1.38485 0.04468,0.0748 0.0752,0.15305 0.0752,0.23081 0,0.88002 -2.964378,1.58268 -6.617432,1.58268 -3.653054,0 -6.617431,-0.70266 -6.617431,-1.58268 0,-0.076 0.03245,-0.15762 0.0752,-0.23081 z" + id="path3920" + inkscape:connector-curvature="0" /> + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + From 37a1fb6b7c82a5477c17faf6ec8538e0e2a03676 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 26 Mar 2013 09:41:26 +0100 Subject: [PATCH 035/213] Adding ingredient.svg icon. I need to work on random-item and scrap container icon. --- .../referenceable record type/ingredient.svg | 1112 ++++++++++ .../referenceable record type/light.svg | 1513 +++++++++++++ .../referenceable record type/random-item.svg | 1462 +++++++++++++ .../scalable/referenceable-record/.directory | 5 + .../referenceable-record/activator.svg | 1088 ++++++++++ .../referenceable-record/apparatus.svg | 1058 +++++++++ .../scalable/referenceable-record/book.svg | 692 ++++++ .../referenceable-record/container.svg | 1899 +++++++++++++++++ .../referenceable-record/ingredient.svg | 1112 ++++++++++ .../scalable/referenceable-record/light.svg | 1513 +++++++++++++ .../scalable/referenceable-record/potion.svg | 1161 ++++++++++ .../referenceable-record/random-item.svg | 1462 +++++++++++++ .../scalable/referenceable-record/repair.svg | 1280 +++++++++++ .../scalable/referenceable-record/static.svg | 1141 ++++++++++ .../scalable/referenceable-record/weapon.svg | 1206 +++++++++++ 15 files changed, 17704 insertions(+) create mode 100644 files/opencs/scalable/referenceable record type/ingredient.svg create mode 100644 files/opencs/scalable/referenceable record type/light.svg create mode 100644 files/opencs/scalable/referenceable record type/random-item.svg create mode 100644 files/opencs/scalable/referenceable-record/.directory create mode 100644 files/opencs/scalable/referenceable-record/activator.svg create mode 100644 files/opencs/scalable/referenceable-record/apparatus.svg create mode 100644 files/opencs/scalable/referenceable-record/book.svg create mode 100644 files/opencs/scalable/referenceable-record/container.svg create mode 100644 files/opencs/scalable/referenceable-record/ingredient.svg create mode 100644 files/opencs/scalable/referenceable-record/light.svg create mode 100644 files/opencs/scalable/referenceable-record/potion.svg create mode 100644 files/opencs/scalable/referenceable-record/random-item.svg create mode 100644 files/opencs/scalable/referenceable-record/repair.svg create mode 100644 files/opencs/scalable/referenceable-record/static.svg create mode 100644 files/opencs/scalable/referenceable-record/weapon.svg diff --git a/files/opencs/scalable/referenceable record type/ingredient.svg b/files/opencs/scalable/referenceable record type/ingredient.svg new file mode 100644 index 000000000..a77a9c8ee --- /dev/null +++ b/files/opencs/scalable/referenceable record type/ingredient.svg @@ -0,0 +1,1112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/light.svg b/files/opencs/scalable/referenceable record type/light.svg new file mode 100644 index 000000000..f8f506636 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/light.svg @@ -0,0 +1,1513 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable record type/random-item.svg b/files/opencs/scalable/referenceable record type/random-item.svg new file mode 100644 index 000000000..0c132ce95 --- /dev/null +++ b/files/opencs/scalable/referenceable record type/random-item.svg @@ -0,0 +1,1462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/.directory b/files/opencs/scalable/referenceable-record/.directory new file mode 100644 index 000000000..e2d80ed58 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/.directory @@ -0,0 +1,5 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2013,3,21,10,19,49 +Version=3 +ViewMode=1 diff --git a/files/opencs/scalable/referenceable-record/activator.svg b/files/opencs/scalable/referenceable-record/activator.svg new file mode 100644 index 000000000..0c6db59a7 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/activator.svg @@ -0,0 +1,1088 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/apparatus.svg b/files/opencs/scalable/referenceable-record/apparatus.svg new file mode 100644 index 000000000..37cef0e89 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/apparatus.svg @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/book.svg b/files/opencs/scalable/referenceable-record/book.svg new file mode 100644 index 000000000..8c041a9e7 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/book.svg @@ -0,0 +1,692 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/container.svg b/files/opencs/scalable/referenceable-record/container.svg new file mode 100644 index 000000000..8c9465b66 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/container.svg @@ -0,0 +1,1899 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/ingredient.svg b/files/opencs/scalable/referenceable-record/ingredient.svg new file mode 100644 index 000000000..a77a9c8ee --- /dev/null +++ b/files/opencs/scalable/referenceable-record/ingredient.svg @@ -0,0 +1,1112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/light.svg b/files/opencs/scalable/referenceable-record/light.svg new file mode 100644 index 000000000..f8f506636 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/light.svg @@ -0,0 +1,1513 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/potion.svg b/files/opencs/scalable/referenceable-record/potion.svg new file mode 100644 index 000000000..552c14f19 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/potion.svg @@ -0,0 +1,1161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/random-item.svg b/files/opencs/scalable/referenceable-record/random-item.svg new file mode 100644 index 000000000..0c132ce95 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/random-item.svg @@ -0,0 +1,1462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/repair.svg b/files/opencs/scalable/referenceable-record/repair.svg new file mode 100644 index 000000000..b1a23956e --- /dev/null +++ b/files/opencs/scalable/referenceable-record/repair.svg @@ -0,0 +1,1280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/static.svg b/files/opencs/scalable/referenceable-record/static.svg new file mode 100644 index 000000000..a6f29370f --- /dev/null +++ b/files/opencs/scalable/referenceable-record/static.svg @@ -0,0 +1,1141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/weapon.svg b/files/opencs/scalable/referenceable-record/weapon.svg new file mode 100644 index 000000000..2e832fff7 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/weapon.svg @@ -0,0 +1,1206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + From cf0c55b37fa033ab6748ffa814a6c89bddf7c543 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 26 Mar 2013 10:28:43 +0100 Subject: [PATCH 036/213] New random-item. Looks a lot better. --- .../referenceable-record/random-item.svg | 1560 ++--------------- 1 file changed, 127 insertions(+), 1433 deletions(-) diff --git a/files/opencs/scalable/referenceable-record/random-item.svg b/files/opencs/scalable/referenceable-record/random-item.svg index 0c132ce95..d051ce049 100644 --- a/files/opencs/scalable/referenceable-record/random-item.svg +++ b/files/opencs/scalable/referenceable-record/random-item.svg @@ -1,5 +1,5 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + inkscape:version="0.48.4 r9939" + sodipodi:docname="random-item.svg"> + id="metadata14614"> image/svg+xml - + + + + id="layer1"> + transform="translate(26.2199, 33.6274)" + fill="#fa0000" + d="M6.67184 0L6.67184 3.5776L0 3.5776L10.8901 14.3726L21.7801 3.5776L15.1083 3.5776L15.1083 0Z" /> - - - - - - - - - + transform="translate(-0.222381, -0.133277)" + fill="none"> + + + + + + + + + + + + + + + + + From 623f9c2a587d1bdeb836c0acbd2c029e651dbbde Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 27 Mar 2013 19:52:12 +0100 Subject: [PATCH 037/213] A new icon for misc iteams. I really hope that scales will do. --- .../referenceable-record/miscelanius.svg | 965 ++++++++++++++++++ .../referenceable-record/miscellaneous.svg | 692 +++++++++++++ 2 files changed, 1657 insertions(+) create mode 100644 files/opencs/scalable/referenceable-record/miscelanius.svg create mode 100644 files/opencs/scalable/referenceable-record/miscellaneous.svg diff --git a/files/opencs/scalable/referenceable-record/miscelanius.svg b/files/opencs/scalable/referenceable-record/miscelanius.svg new file mode 100644 index 000000000..96522048c --- /dev/null +++ b/files/opencs/scalable/referenceable-record/miscelanius.svg @@ -0,0 +1,965 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/miscellaneous.svg b/files/opencs/scalable/referenceable-record/miscellaneous.svg new file mode 100644 index 000000000..8c041a9e7 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/miscellaneous.svg @@ -0,0 +1,692 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + From faf293bd6d1f28827a6209fd63f63cba5d5aec29 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 31 Mar 2013 09:50:35 +0200 Subject: [PATCH 038/213] Removing old directory. --- files/opencs/scalable/Palette.svg | 569 ----- .../referenceable record type/.directory | 5 - .../referenceable record type/activator.svg | 1088 ---------- .../referenceable record type/apparatus.svg | 1058 --------- .../referenceable record type/book.svg | 692 ------ .../referenceable record type/container.svg | 1899 ----------------- .../referenceable record type/ingredient.svg | 1112 ---------- .../light source.svg | 1513 ------------- .../referenceable record type/light.svg | 1513 ------------- .../referenceable record type/potion.svg | 1161 ---------- .../referenceable record type/random item.svg | 1462 ------------- .../referenceable record type/random-item.svg | 1462 ------------- .../referenceable record type/repair.svg | 1280 ----------- .../referenceable record type/static.svg | 1141 ---------- .../referenceable record type/weapon.svg | 1206 ----------- .../scalable/referenceable-record/.directory | 5 - .../referenceable-record/activator.svg | 1088 ---------- .../referenceable-record/apparatus.svg | 1058 --------- .../scalable/referenceable-record/book.svg | 692 ------ .../referenceable-record/container.svg | 1899 ----------------- .../referenceable-record/ingredient.svg | 1112 ---------- .../scalable/referenceable-record/light.svg | 1513 ------------- .../referenceable-record/miscelanius.svg | 965 --------- .../referenceable-record/miscellaneous.svg | 692 ------ .../scalable/referenceable-record/potion.svg | 1161 ---------- .../referenceable-record/random-item.svg | 156 -- .../scalable/referenceable-record/repair.svg | 1280 ----------- .../scalable/referenceable-record/static.svg | 1141 ---------- .../scalable/referenceable-record/weapon.svg | 1206 ----------- files/opencs/scalable/status/.directory | 5 - files/opencs/scalable/status/added.svg | 969 --------- files/opencs/scalable/status/modified.svg | 1192 ----------- files/opencs/scalable/status/removed.svg | 969 --------- 33 files changed, 34264 deletions(-) delete mode 100644 files/opencs/scalable/Palette.svg delete mode 100644 files/opencs/scalable/referenceable record type/.directory delete mode 100644 files/opencs/scalable/referenceable record type/activator.svg delete mode 100644 files/opencs/scalable/referenceable record type/apparatus.svg delete mode 100644 files/opencs/scalable/referenceable record type/book.svg delete mode 100644 files/opencs/scalable/referenceable record type/container.svg delete mode 100644 files/opencs/scalable/referenceable record type/ingredient.svg delete mode 100644 files/opencs/scalable/referenceable record type/light source.svg delete mode 100644 files/opencs/scalable/referenceable record type/light.svg delete mode 100644 files/opencs/scalable/referenceable record type/potion.svg delete mode 100644 files/opencs/scalable/referenceable record type/random item.svg delete mode 100644 files/opencs/scalable/referenceable record type/random-item.svg delete mode 100644 files/opencs/scalable/referenceable record type/repair.svg delete mode 100644 files/opencs/scalable/referenceable record type/static.svg delete mode 100644 files/opencs/scalable/referenceable record type/weapon.svg delete mode 100644 files/opencs/scalable/referenceable-record/.directory delete mode 100644 files/opencs/scalable/referenceable-record/activator.svg delete mode 100644 files/opencs/scalable/referenceable-record/apparatus.svg delete mode 100644 files/opencs/scalable/referenceable-record/book.svg delete mode 100644 files/opencs/scalable/referenceable-record/container.svg delete mode 100644 files/opencs/scalable/referenceable-record/ingredient.svg delete mode 100644 files/opencs/scalable/referenceable-record/light.svg delete mode 100644 files/opencs/scalable/referenceable-record/miscelanius.svg delete mode 100644 files/opencs/scalable/referenceable-record/miscellaneous.svg delete mode 100644 files/opencs/scalable/referenceable-record/potion.svg delete mode 100644 files/opencs/scalable/referenceable-record/random-item.svg delete mode 100644 files/opencs/scalable/referenceable-record/repair.svg delete mode 100644 files/opencs/scalable/referenceable-record/static.svg delete mode 100644 files/opencs/scalable/referenceable-record/weapon.svg delete mode 100644 files/opencs/scalable/status/.directory delete mode 100644 files/opencs/scalable/status/added.svg delete mode 100644 files/opencs/scalable/status/modified.svg delete mode 100644 files/opencs/scalable/status/removed.svg diff --git a/files/opencs/scalable/Palette.svg b/files/opencs/scalable/Palette.svg deleted file mode 100644 index f42475330..000000000 --- a/files/opencs/scalable/Palette.svg +++ /dev/null @@ -1,569 +0,0 @@ - - - - - - - image/svg+xml - - - - - - Tango Palette - - - Tuomas Kuosmanen - - - - - Garrett Le Sage -Kenneth Wimer -Jakub Steiner - - -http://www.tango-project.org/files/Tango-Palette.svg - - - unify - global - theme - color - palette - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/files/opencs/scalable/referenceable record type/.directory b/files/opencs/scalable/referenceable record type/.directory deleted file mode 100644 index e2d80ed58..000000000 --- a/files/opencs/scalable/referenceable record type/.directory +++ /dev/null @@ -1,5 +0,0 @@ -[Dolphin] -PreviewsShown=true -Timestamp=2013,3,21,10,19,49 -Version=3 -ViewMode=1 diff --git a/files/opencs/scalable/referenceable record type/activator.svg b/files/opencs/scalable/referenceable record type/activator.svg deleted file mode 100644 index 0c6db59a7..000000000 --- a/files/opencs/scalable/referenceable record type/activator.svg +++ /dev/null @@ -1,1088 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/apparatus.svg b/files/opencs/scalable/referenceable record type/apparatus.svg deleted file mode 100644 index 37cef0e89..000000000 --- a/files/opencs/scalable/referenceable record type/apparatus.svg +++ /dev/null @@ -1,1058 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/book.svg b/files/opencs/scalable/referenceable record type/book.svg deleted file mode 100644 index 8c041a9e7..000000000 --- a/files/opencs/scalable/referenceable record type/book.svg +++ /dev/null @@ -1,692 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/container.svg b/files/opencs/scalable/referenceable record type/container.svg deleted file mode 100644 index 8c9465b66..000000000 --- a/files/opencs/scalable/referenceable record type/container.svg +++ /dev/null @@ -1,1899 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/ingredient.svg b/files/opencs/scalable/referenceable record type/ingredient.svg deleted file mode 100644 index a77a9c8ee..000000000 --- a/files/opencs/scalable/referenceable record type/ingredient.svg +++ /dev/null @@ -1,1112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/light source.svg b/files/opencs/scalable/referenceable record type/light source.svg deleted file mode 100644 index f8f506636..000000000 --- a/files/opencs/scalable/referenceable record type/light source.svg +++ /dev/null @@ -1,1513 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/light.svg b/files/opencs/scalable/referenceable record type/light.svg deleted file mode 100644 index f8f506636..000000000 --- a/files/opencs/scalable/referenceable record type/light.svg +++ /dev/null @@ -1,1513 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/potion.svg b/files/opencs/scalable/referenceable record type/potion.svg deleted file mode 100644 index 552c14f19..000000000 --- a/files/opencs/scalable/referenceable record type/potion.svg +++ /dev/null @@ -1,1161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/random item.svg b/files/opencs/scalable/referenceable record type/random item.svg deleted file mode 100644 index 0c132ce95..000000000 --- a/files/opencs/scalable/referenceable record type/random item.svg +++ /dev/null @@ -1,1462 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/random-item.svg b/files/opencs/scalable/referenceable record type/random-item.svg deleted file mode 100644 index 0c132ce95..000000000 --- a/files/opencs/scalable/referenceable record type/random-item.svg +++ /dev/null @@ -1,1462 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/repair.svg b/files/opencs/scalable/referenceable record type/repair.svg deleted file mode 100644 index b1a23956e..000000000 --- a/files/opencs/scalable/referenceable record type/repair.svg +++ /dev/null @@ -1,1280 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/static.svg b/files/opencs/scalable/referenceable record type/static.svg deleted file mode 100644 index a6f29370f..000000000 --- a/files/opencs/scalable/referenceable record type/static.svg +++ /dev/null @@ -1,1141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable record type/weapon.svg b/files/opencs/scalable/referenceable record type/weapon.svg deleted file mode 100644 index 2e832fff7..000000000 --- a/files/opencs/scalable/referenceable record type/weapon.svg +++ /dev/null @@ -1,1206 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/.directory b/files/opencs/scalable/referenceable-record/.directory deleted file mode 100644 index e2d80ed58..000000000 --- a/files/opencs/scalable/referenceable-record/.directory +++ /dev/null @@ -1,5 +0,0 @@ -[Dolphin] -PreviewsShown=true -Timestamp=2013,3,21,10,19,49 -Version=3 -ViewMode=1 diff --git a/files/opencs/scalable/referenceable-record/activator.svg b/files/opencs/scalable/referenceable-record/activator.svg deleted file mode 100644 index 0c6db59a7..000000000 --- a/files/opencs/scalable/referenceable-record/activator.svg +++ /dev/null @@ -1,1088 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/apparatus.svg b/files/opencs/scalable/referenceable-record/apparatus.svg deleted file mode 100644 index 37cef0e89..000000000 --- a/files/opencs/scalable/referenceable-record/apparatus.svg +++ /dev/null @@ -1,1058 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/book.svg b/files/opencs/scalable/referenceable-record/book.svg deleted file mode 100644 index 8c041a9e7..000000000 --- a/files/opencs/scalable/referenceable-record/book.svg +++ /dev/null @@ -1,692 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/container.svg b/files/opencs/scalable/referenceable-record/container.svg deleted file mode 100644 index 8c9465b66..000000000 --- a/files/opencs/scalable/referenceable-record/container.svg +++ /dev/null @@ -1,1899 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/ingredient.svg b/files/opencs/scalable/referenceable-record/ingredient.svg deleted file mode 100644 index a77a9c8ee..000000000 --- a/files/opencs/scalable/referenceable-record/ingredient.svg +++ /dev/null @@ -1,1112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/light.svg b/files/opencs/scalable/referenceable-record/light.svg deleted file mode 100644 index f8f506636..000000000 --- a/files/opencs/scalable/referenceable-record/light.svg +++ /dev/null @@ -1,1513 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/miscelanius.svg b/files/opencs/scalable/referenceable-record/miscelanius.svg deleted file mode 100644 index 96522048c..000000000 --- a/files/opencs/scalable/referenceable-record/miscelanius.svg +++ /dev/null @@ -1,965 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/miscellaneous.svg b/files/opencs/scalable/referenceable-record/miscellaneous.svg deleted file mode 100644 index 8c041a9e7..000000000 --- a/files/opencs/scalable/referenceable-record/miscellaneous.svg +++ /dev/null @@ -1,692 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/potion.svg b/files/opencs/scalable/referenceable-record/potion.svg deleted file mode 100644 index 552c14f19..000000000 --- a/files/opencs/scalable/referenceable-record/potion.svg +++ /dev/null @@ -1,1161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/random-item.svg b/files/opencs/scalable/referenceable-record/random-item.svg deleted file mode 100644 index d051ce049..000000000 --- a/files/opencs/scalable/referenceable-record/random-item.svg +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/repair.svg b/files/opencs/scalable/referenceable-record/repair.svg deleted file mode 100644 index b1a23956e..000000000 --- a/files/opencs/scalable/referenceable-record/repair.svg +++ /dev/null @@ -1,1280 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/static.svg b/files/opencs/scalable/referenceable-record/static.svg deleted file mode 100644 index a6f29370f..000000000 --- a/files/opencs/scalable/referenceable-record/static.svg +++ /dev/null @@ -1,1141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/referenceable-record/weapon.svg b/files/opencs/scalable/referenceable-record/weapon.svg deleted file mode 100644 index 2e832fff7..000000000 --- a/files/opencs/scalable/referenceable-record/weapon.svg +++ /dev/null @@ -1,1206 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/status/.directory b/files/opencs/scalable/status/.directory deleted file mode 100644 index e2d80ed58..000000000 --- a/files/opencs/scalable/status/.directory +++ /dev/null @@ -1,5 +0,0 @@ -[Dolphin] -PreviewsShown=true -Timestamp=2013,3,21,10,19,49 -Version=3 -ViewMode=1 diff --git a/files/opencs/scalable/status/added.svg b/files/opencs/scalable/status/added.svg deleted file mode 100644 index e0af57002..000000000 --- a/files/opencs/scalable/status/added.svg +++ /dev/null @@ -1,969 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/status/modified.svg b/files/opencs/scalable/status/modified.svg deleted file mode 100644 index e278ce596..000000000 --- a/files/opencs/scalable/status/modified.svg +++ /dev/null @@ -1,1192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/opencs/scalable/status/removed.svg b/files/opencs/scalable/status/removed.svg deleted file mode 100644 index 17719cfc8..000000000 --- a/files/opencs/scalable/status/removed.svg +++ /dev/null @@ -1,969 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - From 49b5b90cd55ecaf86945e2db0c23dc5a4f07056f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 31 Mar 2013 10:13:01 +0200 Subject: [PATCH 039/213] png icons from nomadic and my rastered icons in raster folder. --- files/opencs/raster/.directory | 5 + files/opencs/raster/actinator.png | Bin 0 -> 2297 bytes files/opencs/raster/apparatus.png | Bin 0 -> 1864 bytes files/opencs/raster/armor.png | Bin 0 -> 1908 bytes files/opencs/raster/book.png | Bin 0 -> 1442 bytes files/opencs/raster/container.png | Bin 0 -> 1570 bytes files/opencs/raster/door.png | Bin 0 -> 1715 bytes files/opencs/raster/ingredient.png | Bin 0 -> 1624 bytes files/opencs/raster/light.png | Bin 0 -> 1069 bytes files/opencs/raster/miscellaneous.png | Bin 0 -> 1518 bytes files/opencs/raster/potion.png | Bin 0 -> 1876 bytes files/opencs/raster/random-item.png | Bin 0 -> 1612 bytes files/opencs/raster/repair.png | Bin 0 -> 1474 bytes files/opencs/raster/static.png | Bin 0 -> 1518 bytes files/opencs/raster/weapon.png | Bin 0 -> 1064 bytes files/opencs/scalable/Palette.svg | 569 +++++ .../scalable/referenceable-record/.directory | 5 + .../referenceable-record/activator.svg | 1088 ++++++++++ .../referenceable-record/apparatus.svg | 1058 +++++++++ .../scalable/referenceable-record/book.svg | 692 ++++++ .../referenceable-record/container.svg | 1899 +++++++++++++++++ .../referenceable-record/ingredient.svg | 1112 ++++++++++ .../scalable/referenceable-record/light.svg | 1513 +++++++++++++ .../referenceable-record/miscellaneous.svg | 965 +++++++++ .../scalable/referenceable-record/potion.svg | 1161 ++++++++++ .../referenceable-record/random-item.svg | 156 ++ .../scalable/referenceable-record/repair.svg | 1280 +++++++++++ .../scalable/referenceable-record/static.svg | 1141 ++++++++++ .../scalable/referenceable-record/weapon.svg | 1206 +++++++++++ files/opencs/scalable/status/.directory | 5 + files/opencs/scalable/status/added.svg | 969 +++++++++ files/opencs/scalable/status/modified.svg | 1192 +++++++++++ files/opencs/scalable/status/removed.svg | 969 +++++++++ 33 files changed, 16985 insertions(+) create mode 100644 files/opencs/raster/.directory create mode 100644 files/opencs/raster/actinator.png create mode 100644 files/opencs/raster/apparatus.png create mode 100644 files/opencs/raster/armor.png create mode 100644 files/opencs/raster/book.png create mode 100644 files/opencs/raster/container.png create mode 100644 files/opencs/raster/door.png create mode 100644 files/opencs/raster/ingredient.png create mode 100644 files/opencs/raster/light.png create mode 100644 files/opencs/raster/miscellaneous.png create mode 100644 files/opencs/raster/potion.png create mode 100644 files/opencs/raster/random-item.png create mode 100644 files/opencs/raster/repair.png create mode 100644 files/opencs/raster/static.png create mode 100644 files/opencs/raster/weapon.png create mode 100644 files/opencs/scalable/Palette.svg create mode 100644 files/opencs/scalable/referenceable-record/.directory create mode 100644 files/opencs/scalable/referenceable-record/activator.svg create mode 100644 files/opencs/scalable/referenceable-record/apparatus.svg create mode 100644 files/opencs/scalable/referenceable-record/book.svg create mode 100644 files/opencs/scalable/referenceable-record/container.svg create mode 100644 files/opencs/scalable/referenceable-record/ingredient.svg create mode 100644 files/opencs/scalable/referenceable-record/light.svg create mode 100644 files/opencs/scalable/referenceable-record/miscellaneous.svg create mode 100644 files/opencs/scalable/referenceable-record/potion.svg create mode 100644 files/opencs/scalable/referenceable-record/random-item.svg create mode 100644 files/opencs/scalable/referenceable-record/repair.svg create mode 100644 files/opencs/scalable/referenceable-record/static.svg create mode 100644 files/opencs/scalable/referenceable-record/weapon.svg create mode 100644 files/opencs/scalable/status/.directory create mode 100644 files/opencs/scalable/status/added.svg create mode 100644 files/opencs/scalable/status/modified.svg create mode 100644 files/opencs/scalable/status/removed.svg diff --git a/files/opencs/raster/.directory b/files/opencs/raster/.directory new file mode 100644 index 000000000..7a78deef5 --- /dev/null +++ b/files/opencs/raster/.directory @@ -0,0 +1,5 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2013,3,31,10,12,5 +Version=3 +ViewMode=1 diff --git a/files/opencs/raster/actinator.png b/files/opencs/raster/actinator.png new file mode 100644 index 0000000000000000000000000000000000000000..0446af22cf7d4238e06d7682ab5ec86127b103c8 GIT binary patch literal 2297 zcmZ{lX*ARi7sr2+b!?S2`22n@r05bxw9> z^a&3Bmx+@u2Id9;@G%8)gk@vqEIv0)41tP1iIu;TIOI)p00=$@0Fguh_{}UuE(3rc z2mq^20HB=-03u$wjn;5xgZ;jl34%$c9T+u5Fu~=8wDV!EKK$z}kN}Mw0O06FAq;FW zly$VLSNgD6cnjljqh$tyiWEP+dLoMS><*1|p{VYgzjG-~6k=+-Tw27pJha7ule}iJ zCjHo-@1Xm~92G#P9X3(>6-s7(vyD7E^(R zY|+H&S)R1roK?+@EQ}5zxj=k?*TJtLS8B4(0LhYFtdwhEGFBDkQ_??mI8^AuH!gID4Sc&3jLI6eP)tANo{PpG~ zaSm&o4Q=0&PfBZ$R67^YrGvI?xmQh7k17<5#{Iyk(x-J43&iRoQPZs6|=c~?~hpWO<)=%C!K4rHq0*w?(Z zOC7`(HWg9=q|J4gPT|rJLH50I$Zb{m>(J6qH** z;dZl6nk-)HhLtzN`6@^G<#C2L5n2$7PHJ~2W*Llvw0!=N3Xu)rCJ08YJdw$~&q&n8!U7?6S7tH0Um~iLog$FC%$~rzyzd zvfo@`qXO`LBSGVy1fHixQF0gKQWA`A32wqu($dlna2G#U{+w+3Gq%HBBl(zo13KOf z-l!a1;>{F0!(a^q%~^@37a&2P)2x5U9HHq{5;3eeD+()`F}UbtW=56ai4&d2AiepB z0wfp*>a=P(j4yAAP{>$tIkrk|l;De4)8qFz(Q@?cc)uh-_?hU{LPXkv(j{s%c6C{L zIR?AjlX|22uF3}(;Pc|wj0|D=?=wHA#-~&t4V8|3CJ3dl%myEZyjlBQ+g`Xb z;3p||IVMz>-}HQ`Lu6ZGDuU~^h_-l8o=9|iTO2|z%dF(v;cE+%hIucUFb$8ron7f$ z5~lHmP`>0ve|NWu@53V#4+Jkpka>lkP8py7A|4y%eg!h9Ua-cl?9l9-do5%mzS^bF z1C8d5eJqpnMK((!5^oJkOpf|*ZhD4Pgktlw2;QqSh?}%JPxWwN-IuMS|CB^n2h7Cp z_RnlIe0#S(-Smh4XGdaiY{)ABwbH{Mde5LDG*b*3jK=LyH9C*t;xzfVQ@FPv-tI1rlDjxq?EYBlwLw^!DnfrR@Cm1rW$W&R2uH zttxR3)!8%fUyoNlrYE|+g0B*SHCvnK(~IZ0>vcJ99R)9Pbk!=LWFw=BT^W2`26E3u z4GTb+=~JG;p}>3kGNR=`U*p);x$u7SzN{B|&UTv!R-76axHpn}NnkM0Q?fX+!N&7}ZvfUC4+I1RD7!v(^TA=g@XDUvE;$?Uv& literal 0 HcmV?d00001 diff --git a/files/opencs/raster/apparatus.png b/files/opencs/raster/apparatus.png new file mode 100644 index 0000000000000000000000000000000000000000..613030267620c5a7680dec1cacb012a6cdc7e5d7 GIT binary patch literal 1864 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/container.png b/files/opencs/raster/container.png new file mode 100644 index 0000000000000000000000000000000000000000..7874606ab9b905dd3afc5e58b929e586241f3fd5 GIT binary patch literal 1570 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 JPDHLkV1nG+EI$AM literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ingredient.png b/files/opencs/raster/ingredient.png new file mode 100644 index 0000000000000000000000000000000000000000..6f9a09d2e93d64c118e7d375868068f77a2b0d02 GIT binary patch literal 1624 zcmZ`&2~bmK5PpP2EJtOSS}CGKZAHsv$N@<}5J(`91VR$7@t7c@bqW$lLI|lEA_#>0 z%1Iz7cpyg;4oO5gRJ1xe9)+TCq7m zwl2011UW>Ki45S~mYS0r2nq;V!>KpM20{?5mQH1n008;`iNz3CiRLNLISn|G z7B6Z7hrp@x<*BfO2He5sK*_1#vTkyDZxlz4-m63lwK!>4gmQ=hV0e2^hfV}%<3lCFsSGa;a*><0hx-bm%}aynOuDeNRx_EA6;&;y7Rb&|MB z6zH?8J5qEEFVx~elUWK3M}|7u7J8^TP%PdisP`-BBG;UY7HIr)8gZ3psRx?_07J!D zic}Y#DMw}3V*y6o>Ip310koMi6kqKJ$Pc#!a#ffQA9XZAP^QdRd}6Cei{mPmgCGJ3 zbDNg&K^5?dZv3Y)F)q-xky+VCRSh$%4K&3NLo*UzcY$8p zA5+>z)?7)bABit$3p?5orW|H~Im!lNmBY-^?nuQDQ>rJ+2V=q1r1}W($#v)H@_|^O zcC|6O_B_4jTucoh>0TDUSQlPxq*WPcg`K1-BMtOpZsPmYYmwBD{Xltk|%3{zjF_{C>0bnla1I&cm3=@jk8Cs>|yB{3i@piO&Dm=YBwc<2o)jLk-_CN4mpVneqbiS8q<8pS(r>ABnr_}@O$qk3B((Xt?hc}eSy>=RT_p)NW?(Cj&@{~!2 zuC1<4eB9EU>UM{c&@QVBlh-BCcUaf$GG^(jQO160s|z)E_CB97ioNw1+wAb4zoe~oOoJa8{VgxwfROgLjP8by z>o~9H(#QO+F7##x2!@8P(LBY26IMxi$M1&X#?L!Z@yEv>>62Hv&Le6%4qRP$zJ9G6 z`{9LyOKd@oAVc+5v>V>->Ce__c0Sm8o=#a}FPPmX@{4QSk8gVPoulbA`)2nn+8H@Wt$gpbB9Q&2 zg~D}yAu+sk!$7dN!NDZat36-^Hu6Y`ygkXhR65KM8qP@|+EMFu6=|{j~ zJdr2@5~+5&Vfj}=dd8mpdxig>Fc-rQ1qoj*S72uBnf7!9< zX67ZO3laK!FGA{SgzOknTM#NI5L(Jbh}Dcxu%fk3!p3>0#c5JLCV*$G&A`J>Sk(ip z0a(FifR&qYzZU-d3G6dqv$|OhBdlv+=Cn)yDg0g!Py4`z`Kw@CfM*l1(gixTYx+1m zYKM(6fCaEGf^8BWUvipME?qe+o`;Q50E@en%?PX4T&4=wOc^Y7fn5*li*Eesgv(In z(jSAhL9j2uXpCi;GdGa6G?;B2=Q*aiaFg@oF55a52P3hL-#CtGKHTGw`ZV}QtqsdT z2wSY&@tnn>XFd;l_HJCuCG{dOBzridPDC1I&bcp~mL})?m!zr4sZH@5!5=x~Y^lrA z=$u!B;jjmEnu?vX%D-mM-e?QIawfj-T=>FJ;@!)vJ6*Bk-Avup1X7nm8s8^p%N^z# z(tM13P(bR1H9R&`j&@@Au`*qhfzYNM3A=n~(eF)`vx6vvtd|@p zX3=PT^}=$4c$?3`uO2zhNVa=LeQ35HkN4dYKW0eXMr~a-_ry_#N$dmCvs6EnDt$AhnzVzpGT5#AN?`HAdx14FXFXe+&0T0zucP8QB zB}Gzp8UBm-rRWZdk1DzagO8JWTq*NTUas2f;EUJQb>G)C(ND4Cyx$Ct^$QnOBvewk zyJZ2Ah$FPY&^J0t+vWN5ihT`PV(FOVkR(&n!O1z0v0rdlkmYyr^>w;$*|*;a6^>g| zY+rOW%^Y&#lECoqP6C5 z`h$ACdSCHZ47c@bG@7lQ{XQeBLl^powOYT4@1T~T6AXoawUItR*!+*w`__z{ z9C$YCPYq~P6beqv{TM(A*!pVl`G)4|m){;`F!qgbo6dfBuCXrgvuwS82!fbO%gMG( zE7l#Vozo?+% z{}a-fl^Zx=ySqb1Nr6%&E0rUaN)=Z0NpV@8Od$^|DJ^VSW`|%BO6H4r-HEwXe*-X~ B{}liL literal 0 HcmV?d00001 diff --git a/files/opencs/raster/miscellaneous.png b/files/opencs/raster/miscellaneous.png new file mode 100644 index 0000000000000000000000000000000000000000..b6cb250400cb65c921d4ecbeb3ed0ec5cd0ec014 GIT binary patch literal 1518 zcmZ{kdpHw%7{`C3&1Jddek~#CqUJIQhh%Px+(taeT*hW&%Wdl67?o1F9nNGVj!QZ@ zN_E1BNlF}>xrIeTb2}14TIqD=&-2H5pXYr)&wKek-~Zlhud^<4vRbkL068~Tl#iHt zJ1Gql*Mv)#HpJK!?cm`6Kw}G=Tk!%Ge#QkQrZ_~7t?6ROP+S8O#Ma+-5(1|pOT~8WZYT## zK-Y762ua0H<#qZNdztM{ZTk56GF=Vd`O*m8=;T@lOH+Jr;jJIDx+jNmeT=% z!;SfH>?Y*=#+xyG1tdZx(?MiBY3u+!B*fX%vtnCu)a0lJ1>UQq@n@}qS;NA~@dS?O z2fJnKuiT1Le^2pwCN%*cYnS~vE4a3SFQg&az&4_8Qsb2=B)vL$qt-%UdqtNS0s?!& zIaR&+0k!fkyy4_?ZCKig_L&rJzVbt1a8^eW^V2TcdHks*X0fo|X8%vuZnzgs0(_fhCM^Kk=0S6 zz{boE0?5rGY>@B4@Ar6w{X|Si@m@Wvl#Gy@S|@KWuG@ayH`O`PZfVK62rt4m3KyjC zD<1-$rIQT~(TMXWdGFqEN$F&pTAyt#Ld|rg?zX8m>xX<;s5bn{Oj*&pyJTonqSv&# zSM{!LQ9Y+T6BZ0p8T+n#HP4u)I1Hye_0~VgTNB6)@X)R@>?7I73d^o{;~C0eSH|t2 zTcN%ffm{Xr=(Oqn159Zpb&2%KnS$iK?l~89GVl}ZW<|`L93LISNJiA#Za6DTIi-`2 z)IiNJe=NLMQ<>?=`T(KC889eA>p86B)~v$n>fRqZD9frtc@R)J*nvzM)Fwm=>cOm? zzoAa9q&xQnRmmyBtsV4MotB0{Fj0aVF-XTUc|>Z)H~q<@i&tFo61k66A91PO}5~Ma%)#AX^iyCg>7p-L`F}33|5ZJ zyQ6)4$j)zY%GtSBUD0l&>x}Ly^pwA&@ZfJRth{4?MRhUGD@ov58XmZ5dItDgsL9@G@sDZS;@VeDo@~M{^|do61}hu~ zG&JfcbAB(gs_h;n*|r$rZ;_7+$Ni*Lg+((XW_2MT#J+0;R7Cnn@7Y%(ohr=L+`{ zrlF;f_H#0RSrzImYuCfR&!<6L;z}}u)mCkexQ9%8u=9Nu9XB_V9vSh`dlt-0mWNo! zD|_ba8M0DS?1E9FP}&p6&O54|!&yG-bCN%+lT0Qvnlqc>-OkRNTKR*%50uNSVST#B zrL~irmPa|wd2C@_eL+8RZObuhy-nb0BL6kEuXMRak$?D2z@WWV*f;r4%rcF@rJB)b zQY@ZPT~&D38&VpT=I>cT7(I86@rGW(k%4!X%sbTRrK&4WT5#opm5n&YEF>-u#>58qE P_z1W;okcaA#%BHtUqPk< literal 0 HcmV?d00001 diff --git a/files/opencs/raster/potion.png b/files/opencs/raster/potion.png new file mode 100644 index 0000000000000000000000000000000000000000..e644017641207da2d8858c2c8b00d0233239f55e GIT binary patch literal 1876 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/repair.png b/files/opencs/raster/repair.png new file mode 100644 index 0000000000000000000000000000000000000000..a8165827790baac034005d1b4729b02ad45e5f70 GIT binary patch literal 1474 zcmZ`%cTm$;9RFbrib}OARwz`joJC8~jDj>q4Iv98h+!{f2W13e0umr3fsh19f+T22 z$bk?MWQ9l)2pE>2oGb^`sy%Df7VF8<_D*s1(cbm!AN}6veb@Vb?|sJ;2l$h0*Ep>U7^#B(;v@M+%+D*-d9-X=0IC#}EJUWoYJ_*W*JQ`Zl zpwhO~NaSJ;kDW?S4hZxQ2tJ(4J=JDxl2=LT%v4`r($1Ybsln8$8il^QwawU=LQlqc zWAeG|JZ?^XW38d9!!p=ovgngi60lgTgM$N+Ow3@UilxPMO*MEtrqk4+P@ZmV)~aii z3A8w4uTE!bj!ih`;^Gn=6E2kSHT7pzwF+)=UT8#M#L=*@s9;drDGn)IibzK+RO#n^p#wIYUHbY~p z;X==#VPtIJQcr7VZ=0#F!#rr{8!-=$4UFF!othr&9WwO|cTY`^Pu{++Ij^j)KclKs zsO!#Xv}aZ46w*p@NqLc=l*=v7&E;iD6=HLr(K2M#XqB9zoB}~kp_n6*6_!>A#j?Vp zk^*gW?X`)an|CH|-I*L3wHSJJJYgPRln>@vCKpO8OXO7&ae0wY!t3h4q&inAlJX@A zQAJf5=m?N(LD~m|oJsW$ged-$L%u#fBq9Otjq}1DJg{s1UKA3EL?GaBRL$Q@sT@~q+xk?@cR=0paDO$Ip}{90SEA=@RZwb|}!5J2<6dj)x3kB`~P z;GPy&RS7C3nnHQ0T6k7=3>zTw3d0BaMd7Hv5yTLG&f?|`N_5(rGJ6zlLbabZ8wIl_ z>`1f=c4ygA++O6oblHPlgQ=!c^}4o{Ceo$DXkRJ!eQZ+>1VmRobMjk`JwX3g{T{wCRd>&nOF zKiJwtud|MQbXV*ARejx^mS_`aXvFYET-;+OV)GUHz23y<#uxjtX7635%~{^rh-cPR zcsO}>{WkT;nIv;Mn7MfS8EQ0naTjf}`aXjLBM%5lbN57BDoPr*yX|*Ix$bk>yQi;K z*Vv`)Y;i2OIn~5fA^79la54P90IMH;i~s-t literal 0 HcmV?d00001 diff --git a/files/opencs/raster/static.png b/files/opencs/raster/static.png new file mode 100644 index 0000000000000000000000000000000000000000..b53be12d9a8abad9272fdd7c6a75b1d3a6a494ba GIT binary patch literal 1518 zcmZ{kdpHw%7{`CZTxJ-Cxok(sA*?NQX1O$0o0FJZw8|yq&RlA3g(EHywCH#pXa@NpYMM!kLF9!f|WyX>)eRte=7=CC15NLd8sXdC>{K1z&!_ZHNLb7(&-i^$pDsLJnXU9&72fI{f-7|m zF|gqUd$2u!OSOjh@6iC^h~i{P%*wgaiH@`4-IlW$(-}guq2X=ms%UtDxHc6RUGQ5| zQ>zhiyz0XC}*TygO>%+5Vz7uDl-HQ;)|U@va&5yH@D~XW#<`! zxrI|=%kAnb=H?bkj$U-bym(m7kxFM(ZI7d;E13(2NPkEy1{u+86aA1ThWx&ANizhH zKo`He$h7_2yn%^F_TqCh4xh2V#;wptNIlzEeDFgs?Yd>dXkZ&%gzer{=rwAv>;$*b zX`!pT>D12EEyG-OZamvM92e)I$D?Cf4pAUz)yG>Xo9H290UDwJ?;Nw__%n68?LEg@ zn`h@r*cTwtNv2~WmwqAso-c3e;epsl!$MSb#k0ie*=Y;qeHLkDWwf=g&=isQT(DD3 zXqc)RBse4_M#uj_(sLQ%s}YtqGoWw0-r&1F^s4qm=fc>-PZf>?nap1e2M(huDoCgT zf^1c!rk|G75Y>lcFFVbfntq@d<1I|cr~y{Hbbzkiz1{CmTU6j+>k)ole0Tp$#JluH zf73FkZUN5TZrr*up9b5$c?+_6TKc#W$;MF5Q6HwM;BSTt61JW!(KSAd!8>w|2V0@K zwJn{K)@Td$5%Sau(B&GZC&6j3$K(6RlNvohbDihp9JlJs%F?x$?My$bR=-l-Zu@E3 zi)%q0IpNlAj;D$m&l)rd1oy88Ew*`g^gCd?tIl5<9JzX zW%9t+wQudFPx#aV%X9iq>UJbgL>9=hST6jV^nX@aZ$dVFDtqLXL=lRDH)z1T++~Zl zDV7bT7zj=7x;-{lxH7x5SZRK5COy9~0gixo_0I`!c3|5Dg2m(~(OXGfTQ-JSvB=7_ zqT;CT8*!;w`?SB*evbZ$$MDcog-EF7D9>H~r4-RjcK+-wsh!J1&|A}%l3(;IRJ;yR zdq%x-ry!Jn6l1TlN*7eS=tiK9Rp_?T$LX`*h9bGM6BmYiO9!|Y$KDZKH0q`nJ|7Gg z-W9HE!?=@GFujSr@Qei5TceF%CyOylHr1yDWn%qDkJ{HH=+%T^tHFykf&h(*0qOo$oL@Y0gLN=l)Plry|+wLh+UFZ8q_#K$TFFVZf*vCKO!jdRXx>{REYi(=3D{98` z@zcj()PBW#Tc5ctG&4FfGlm$I9-{!*gu^>J;2a$s@j-YT5x1G>>|%%8M8x5iAN=nA zA3<_zbo>F<{|gGsk;fDQ;~x%zsRuHdk?Apj$z)>VQxY?xA{jB*)b!X&iK~g?2zYPv KB{z9S9QzkRt&Y3^ literal 0 HcmV?d00001 diff --git a/files/opencs/raster/weapon.png b/files/opencs/raster/weapon.png new file mode 100644 index 0000000000000000000000000000000000000000..b68878a54abbadce500135ea0dd77e7e53168118 GIT binary patch literal 1064 zcmV+@1lRkCP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000A*NklC~g8kO*MPy}%<;wSyJmZstM`E*dS zB;<&=YZ3vchrGk4fJgJ68{u|#p}o-vm0Vyaa6T{jpGm`m#mI*?I~hDq;%Z9r5miti zn*vPDcMbUY^&#dyHRC~@7P9Qrwfi+E(0MZhHO54wat<$VgtM9exh!8P`%`mKgD)TM zVcOn+h8s#Kb5bKZXFUO#RBG?)>Ow_%`FfREg{il<;doPvTbHHCI>}uNch0H+0>4vV zkJ;H-EG#U*WGY#=l*lnLbQR+-t6{ZdB3s0>M_PFM?tvhDdU_fwD=V0pnZd}&2xyaO zou+bO>#4-6CuOKUCqkBx8=4MQ5;#Lq{lqze`~7~*&COwKYz)K0!|3blLt&wDy+|v; zKu0m2HyZdo3*t*w&1&3 zLRv#?hB4ku>fFzO4YILZONU zS11(z{lKFNAn;O}c5UaJ4R}NW1kSA3-|>KN5kTO~@sfS+cDoU&=BL$aA2St}z1BSH zCJe&KhlF%`Jm8@OE>%?>(`mJyAl&QqZt3=XmC7Z~$O!$*v6cXVlbT0^x3#rFE|dK} z2zVfY0-eq=I5-%HJ=}RqOADAW^BxpDAb_H%ccY`D@OV6%Vvh$rAb^?o?-LUfAcvHJ ztXBeOR;%YAoriwOsKP?$(9jTUHXFLTyV2Ct6sWmIqdCS_qiuIj0#jor(+5t2!SJ0K i#dmqRxsG_jiLn1=-XV(QI6oTz0000D> literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/Palette.svg b/files/opencs/scalable/Palette.svg new file mode 100644 index 000000000..f42475330 --- /dev/null +++ b/files/opencs/scalable/Palette.svg @@ -0,0 +1,569 @@ + + + + + + + image/svg+xml + + + + + + Tango Palette + + + Tuomas Kuosmanen + + + + + Garrett Le Sage +Kenneth Wimer +Jakub Steiner + + +http://www.tango-project.org/files/Tango-Palette.svg + + + unify + global + theme + color + palette + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/files/opencs/scalable/referenceable-record/.directory b/files/opencs/scalable/referenceable-record/.directory new file mode 100644 index 000000000..e2d80ed58 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/.directory @@ -0,0 +1,5 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2013,3,21,10,19,49 +Version=3 +ViewMode=1 diff --git a/files/opencs/scalable/referenceable-record/activator.svg b/files/opencs/scalable/referenceable-record/activator.svg new file mode 100644 index 000000000..0c6db59a7 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/activator.svg @@ -0,0 +1,1088 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/apparatus.svg b/files/opencs/scalable/referenceable-record/apparatus.svg new file mode 100644 index 000000000..37cef0e89 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/apparatus.svg @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/book.svg b/files/opencs/scalable/referenceable-record/book.svg new file mode 100644 index 000000000..8c041a9e7 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/book.svg @@ -0,0 +1,692 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/container.svg b/files/opencs/scalable/referenceable-record/container.svg new file mode 100644 index 000000000..8c9465b66 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/container.svg @@ -0,0 +1,1899 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/ingredient.svg b/files/opencs/scalable/referenceable-record/ingredient.svg new file mode 100644 index 000000000..a77a9c8ee --- /dev/null +++ b/files/opencs/scalable/referenceable-record/ingredient.svg @@ -0,0 +1,1112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/light.svg b/files/opencs/scalable/referenceable-record/light.svg new file mode 100644 index 000000000..f8f506636 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/light.svg @@ -0,0 +1,1513 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/miscellaneous.svg b/files/opencs/scalable/referenceable-record/miscellaneous.svg new file mode 100644 index 000000000..96522048c --- /dev/null +++ b/files/opencs/scalable/referenceable-record/miscellaneous.svg @@ -0,0 +1,965 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/potion.svg b/files/opencs/scalable/referenceable-record/potion.svg new file mode 100644 index 000000000..552c14f19 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/potion.svg @@ -0,0 +1,1161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/random-item.svg b/files/opencs/scalable/referenceable-record/random-item.svg new file mode 100644 index 000000000..d051ce049 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/random-item.svg @@ -0,0 +1,156 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/repair.svg b/files/opencs/scalable/referenceable-record/repair.svg new file mode 100644 index 000000000..b1a23956e --- /dev/null +++ b/files/opencs/scalable/referenceable-record/repair.svg @@ -0,0 +1,1280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/static.svg b/files/opencs/scalable/referenceable-record/static.svg new file mode 100644 index 000000000..a6f29370f --- /dev/null +++ b/files/opencs/scalable/referenceable-record/static.svg @@ -0,0 +1,1141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/referenceable-record/weapon.svg b/files/opencs/scalable/referenceable-record/weapon.svg new file mode 100644 index 000000000..2e832fff7 --- /dev/null +++ b/files/opencs/scalable/referenceable-record/weapon.svg @@ -0,0 +1,1206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/status/.directory b/files/opencs/scalable/status/.directory new file mode 100644 index 000000000..e2d80ed58 --- /dev/null +++ b/files/opencs/scalable/status/.directory @@ -0,0 +1,5 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2013,3,21,10,19,49 +Version=3 +ViewMode=1 diff --git a/files/opencs/scalable/status/added.svg b/files/opencs/scalable/status/added.svg new file mode 100644 index 000000000..e0af57002 --- /dev/null +++ b/files/opencs/scalable/status/added.svg @@ -0,0 +1,969 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/status/modified.svg b/files/opencs/scalable/status/modified.svg new file mode 100644 index 000000000..e278ce596 --- /dev/null +++ b/files/opencs/scalable/status/modified.svg @@ -0,0 +1,1192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/status/removed.svg b/files/opencs/scalable/status/removed.svg new file mode 100644 index 000000000..17719cfc8 --- /dev/null +++ b/files/opencs/scalable/status/removed.svg @@ -0,0 +1,969 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + From 01314b7c08e25ca4376e38bb97fc148e0217a208 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 5 Apr 2013 12:08:35 +0200 Subject: [PATCH 040/213] addin more nomadic icons --- files/opencs/raster/activator.png | Bin 0 -> 2297 bytes files/opencs/raster/apparatus.png | Bin 1864 -> 1580 bytes files/opencs/raster/creature.png | Bin 0 -> 2506 bytes files/opencs/raster/leveled-creature.png | Bin 0 -> 2212 bytes files/opencs/raster/lockpick.png | Bin 0 -> 679 bytes files/opencs/raster/probe.png | Bin 0 -> 583 bytes files/opencs/raster/random-item.png | Bin 1612 -> 1993 bytes files/opencs/raster/repair.png | Bin 1474 -> 1280 bytes files/opencs/scalable/top-level/.directory | 5 + files/opencs/scalable/top-level/gmst.svg | 1047 +++++++++++++++++ .../scalable/top-level/topic-regular.svg | 1045 ++++++++++++++++ 11 files changed, 2097 insertions(+) create mode 100644 files/opencs/raster/activator.png create mode 100644 files/opencs/raster/creature.png create mode 100644 files/opencs/raster/leveled-creature.png create mode 100644 files/opencs/raster/lockpick.png create mode 100644 files/opencs/raster/probe.png create mode 100644 files/opencs/scalable/top-level/.directory create mode 100644 files/opencs/scalable/top-level/gmst.svg create mode 100644 files/opencs/scalable/top-level/topic-regular.svg diff --git a/files/opencs/raster/activator.png b/files/opencs/raster/activator.png new file mode 100644 index 0000000000000000000000000000000000000000..0446af22cf7d4238e06d7682ab5ec86127b103c8 GIT binary patch literal 2297 zcmZ{lX*ARi7sr2+b!?S2`22n@r05bxw9> z^a&3Bmx+@u2Id9;@G%8)gk@vqEIv0)41tP1iIu;TIOI)p00=$@0Fguh_{}UuE(3rc z2mq^20HB=-03u$wjn;5xgZ;jl34%$c9T+u5Fu~=8wDV!EKK$z}kN}Mw0O06FAq;FW zly$VLSNgD6cnjljqh$tyiWEP+dLoMS><*1|p{VYgzjG-~6k=+-Tw27pJha7ule}iJ zCjHo-@1Xm~92G#P9X3(>6-s7(vyD7E^(R zY|+H&S)R1roK?+@EQ}5zxj=k?*TJtLS8B4(0LhYFtdwhEGFBDkQ_??mI8^AuH!gID4Sc&3jLI6eP)tANo{PpG~ zaSm&o4Q=0&PfBZ$R67^YrGvI?xmQh7k17<5#{Iyk(x-J43&iRoQPZs6|=c~?~hpWO<)=%C!K4rHq0*w?(Z zOC7`(HWg9=q|J4gPT|rJLH50I$Zb{m>(J6qH** z;dZl6nk-)HhLtzN`6@^G<#C2L5n2$7PHJ~2W*Llvw0!=N3Xu)rCJ08YJdw$~&q&n8!U7?6S7tH0Um~iLog$FC%$~rzyzd zvfo@`qXO`LBSGVy1fHixQF0gKQWA`A32wqu($dlna2G#U{+w+3Gq%HBBl(zo13KOf z-l!a1;>{F0!(a^q%~^@37a&2P)2x5U9HHq{5;3eeD+()`F}UbtW=56ai4&d2AiepB z0wfp*>a=P(j4yAAP{>$tIkrk|l;De4)8qFz(Q@?cc)uh-_?hU{LPXkv(j{s%c6C{L zIR?AjlX|22uF3}(;Pc|wj0|D=?=wHA#-~&t4V8|3CJ3dl%myEZyjlBQ+g`Xb z;3p||IVMz>-}HQ`Lu6ZGDuU~^h_-l8o=9|iTO2|z%dF(v;cE+%hIucUFb$8ron7f$ z5~lHmP`>0ve|NWu@53V#4+Jkpka>lkP8py7A|4y%eg!h9Ua-cl?9l9-do5%mzS^bF z1C8d5eJqpnMK((!5^oJkOpf|*ZhD4Pgktlw2;QqSh?}%JPxWwN-IuMS|CB^n2h7Cp z_RnlIe0#S(-Smh4XGdaiY{)ABwbH{Mde5LDG*b*3jK=LyH9C*t;xzfVQ@FPv-tI1rlDjxq?EYBlwLw^!DnfrR@Cm1rW$W&R2uH zttxR3)!8%fUyoNlrYE|+g0B*SHCvnK(~IZ0>vcJ99R)9Pbk!=LWFw=BT^W2`26E3u z4GTb+=~JG;p}>3kGNR=`U*p);x$u7SzN{B|&UTv!R-76axHpn}NnkM0Q?fX+!N&7}ZvfUC4+I1RD7!v(^TA=g@XDUvE;$?Uv& literal 0 HcmV?d00001 diff --git a/files/opencs/raster/apparatus.png b/files/opencs/raster/apparatus.png index 613030267620c5a7680dec1cacb012a6cdc7e5d7..037ed290fe9d5fd538bd21f9eda35f83d5048069 100644 GIT binary patch delta 1547 zcmV+m2K4#J4y+82Bnkm@Qb$4nuFf3kks%X*32;bRa{vGf5&!@T5&_cPe*6Fc02*{f zSaefwW^{L9a%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000G>Nkl%ilj80$5+v+~wjEsV4FD4J??VGdK*?aA^_Q(5j)v7OKfud=nF?3F;5SIhs zdGhdrm6GzZvYqJdJ&D9b{hP3LG9Ql;2n-O_H#X*Dc6JzN&lW+Yl8$(k0JR_`FE0ag zbGPvDp##au5q~L_VzZ}6@Q46EEiGn$c6_`G&!11gYAu8+STgG|0t`r}Q%u`zHB^QB zxOJ-o+qat$tn@GR1PM;@^x_ewgX!r}+`n%_eSI!fLHviu2n5MQ*5cwUJb2*1Cci$wpW#k+5uxz{aF-ByBKY!+Jf| z(@9L!!EDyToS;F1Nexqc7~k!NT61W!S`MBnrAX;U6(Ickox;*1bcArUN@L2-M-z4v9WfH zj$XjXNGl2S9JS^w3A70V17~pcY6EPxQtoZ7{rn7#bbBfCey*|g>6rjXD0x_GgFv0*MYa;)r5r`_!@ zXW%DK{)(KOjgSWsfpCLzj){=<-08gP*0R3^KYsidWM^-HRO&s)1rh7b%*^j3uaOje>z#P9Z#N&xkYeG!AnbjKth5HLcy9^wvencnbZq? zeKp*ujgMdctZH9>3SL(BBlhgEkN|xa81~yVoMIocICeU(eYR2i5ID=1j0_zFe6J~% z#2f*I+~53dY9!5b6=yPIW1atd&Q}6wuMZ0ofY0~h_RhsH68rm37Zqia;k0oM$0GT^ zn#@YzhYn>@<|yIqy?XlXwzWurc0eDMN<3dt@iPgLxnM7U?DkXt+Tm6LFDc1FW~Lq@ z(VBUoz-#f};JL6ehi$AomBeu0`-2!ySwJH-!MPX z+IkkLOszvhRxVh2da6I^?Vkdd2YJK$o7MG87v1*=u>VA*!f!q;EdslDuSY>aIz?>_ zmuf6-R|=MYkM(@>W)1BW0nqD(WISH;3}eL#goKDUF>sdY4##PV&U%W@TFU+=E>gR@ ztCpqOhrlZx2US(s+;YpTmpw+K@r6j}wP{5HfdPE8#iFG+Jw{6@d-3vRf?dwq z!{+(Ok?(Q%@HQ}Y7Zz^eK=Si9p}2S(*hC#XxCIAx4y1G0zjJ2-LPOWWXYK0ue*2bb zKq~QllbWhS3hjaxi<;K7FeD|dqZKWLN~xmtESPLmiTHRqt!6>AmdOwk9e}7PDU3!5 xtz%+Z#r$9}h`6%rw0!R6YPAmof3s8re*;>O4EKC1no$4%002ovPDHLkV1nah delta 1849 zcmV-92gdlU49E_UB!2{FK}|sb0I`n?{9y$E0004VQb$4nuFf3k0000WV@Og>004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00006VoOIv00000008+zyMF)x z010qNS#tmY4f_B94f_ELcQu;;00tOIL_t(o!@ZVmh+J10$AACl<=&Z{$?QzBlV)}{ zBu&T*DQSF3X(0Vz(nb-*60{mbD3q28C5t3bKZzhg@rw{@G6XD$_#wz*P}?YBD~Qw} zwhKzl+E(H=-DbPHnH^_$cJ}VQ=bY#9!@YN$jM?1@*dBPeGw0kn|KIa}o_p>HY%pG} z)wZ^c*+R?}Eq~?qxkh6!tM$lo5M+c9^IM087Ja4W9q^$977DrCd!K*qIlIxm=@4rz zymIN%(e~=FLpz$HsoT9)Rkd*!SRruhuSK{>)z|C$;Z+$oM`oo_AOH zo(E5B_)0-*-GNh5LIP;ET6pdHb-%oM^ONUJpKkneeEctK0qEX|Jv(+B4OUm-YYjgY zQwqM;(0^J(NeLwcAOx5hjtG_r#uykWV@nf<7Me|A!|-tcKkggAwpw#PID58o`RY}? zd-EndrI7Lc7$_-+k`h9Q*nT2J)FFEmmEeB><{OQ< zHc&bF#1nAGk7J?P#LcNGv{zOjr35<{_W&~(fPat@ju}cRRJLuy-d($JX#akI2tlg_ zBAUG~fIF?087!4RL>MZUarDtgkmVmvuBjCSsgz5%x8^UvqA*+FuyW2+DXLds6aq~nEB05fFQnn;>cBqbti z=f8R3!kxYVjvYHDvRZ!yK-}5Rp;Rcu07*z8Af<%V8d51x(huGDq)&mhmcrH5*Ra8m z>4(*&r3Z!zg#$zcV{N>7Vr80D#|5S0Lw~6!`;G$uf>w)#5Wm<6pyNO(mm6ka3lYIt z3j*R=cV%^#3n@U?dVGnm%gyHBTU!62Z-5|*4hz6{&Vl3l+l*4W<3K8sI3cwLr0mS0 z3u1Y3(OP3Jzj*$<>$?Ow-~TL_1vv+6E#~X>YfJUI>HUF7vXtqm*E5{8n7?&v#eW&| z(njKU0SGBSk)CWp81j2_a~JBjZ~v*iw8UVJZ%PgyCPL~|@0gvMiiqf`(-$uWeFIdh z)r=NmhjR{56rtH_&AmP`agD9L&}uX+5Wo2t05gM_K?y(_NW#lz6@Za`#5({Z3?+uh`>Z3=RnqihyWs_4l#i8$cWNf*J`7qyZZw8 zYhChq?uEiIT6TOIBUVqb>=&e0IGZU4hW@w|MHnL zdP4vq7qhb`CDt*wcC-S18Et8mC!OdS4RM<3ide`C`$_6^rL;XU+_--viA5bVOvGgRvHo zG5GYMLmJ6O+>?2y1jcl}vvYSjls+8;`Meguv+DuqiOI>=k3RhHuO;v~2!SAqu5i1( zv%R$RnD%|e-L+5ccMd{`PJbDQ=)Vpy15t$CV`IG9Y=*nve!KcC@WZ4@f13gR*bUG* zOO6~o_$kL6e*2+^{s91uYV{jR>mTJxrQ*==u(zdJm8EhSem)QFdGS9Y=U~DR!SXU% zjRx*aPn&QuV2|VJNwrD8#h`EjNfCsp947GC0^eU;2uCqFngZXJ~7+! z%uE0PC&$LF0C>DBvBDZ#EG5^v0KRp<`s@w%Ck*iQ|EqWx#I-)ePkkifT@b%p z2jHt8sdyK})q99P^?$L5cR~E7OZ>|pt9Td0r3g5=*7|<{JnFP0r1W5t0000bbVXQn zWMOn=I%9HWVRU5xGB7bSEif}JGci;#Fgh?cIyEvYFfuwYF!;jw!~g&QC3HntbYx+4 zWjbwdWNBu305UK!Gc7PPEi*AxF)%tXHaayjD=;!TFffUqKr(m$000?uMObuGZ)S9N nVRB^vcXxL#X>MzCV_|S*E^l&Yo9;Xs00000NkvXXu0mjffHPMs diff --git a/files/opencs/raster/creature.png b/files/opencs/raster/creature.png new file mode 100644 index 0000000000000000000000000000000000000000..52c41615adece79dfabeb4ff91ce1a40fc125754 GIT binary patch literal 2506 zcmV;*2{rbKP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000R&Nkl&0tN@bMn&hz>-)QjA$5&w34?I}#)EM6`$x zn>Pty2P^^rdNif4Sj`$K(1uJZmb#y#-Djb(*o;9)er*<8e4K9CNi4z|3TRw=#nP zKQlW5yJ8JU^Yz9ilNLvkjaW$n_)0Is?${u7lluo8Ay^k8N2n*~7m76{0QyISOx$;f z0RE*S3BwI@@o2>yCUXjYy*Li1G9$3fqGKq(SDl5vVh00$GRuNPNugM+_r*?|4u_nf z*q;!Lz3~Q|Otav4iW%FZ{IO6jfR@MZo2ZRXL}>LDOYOdrSKlUE&`*H-2?HZ*itu!8 zDITqwhu(S7=pnVI=fTokCVL9ronc~Vr$8TNP|f5>+a|f^bz3mg|V1zHo$7oVU0a-oc76? zFAdjVmfj!EAR;z!a4r5*{@fIR0B^h56u!%LNf@?5qk(r#t+@W`^#t?@7R*MGff_;%A@PMA< zF~yvwFc9r4db&3*gvp$OUn@<-^2mU3aDz-V1)Qp#);vHYV1f_}g(wQ}VZb+=RM<#Z zD3fsD&vt)0MFW%;laFYK>6`eAE?23yQ( zEYo_!!1Wk*Gy8}}uNTJSd7}$|-&TWHtyLJ^T#4t+OLL-eF~^4ealxon3!z|pjJlEf zkM`!pV0c9?UNo2C`z4upP@RE+$~5#50VY|3uxXhKKYrhfESni7F`<)8wH%U>OUg$9 zp)}o_0}G!8gC`dbqYho$R$^X?1r~of_Bq2yzy@@Z3Hc{t(>sWcCMJ64zF zVBeM%IMvaJ&UF>Ahxwzf(1{R*c%1f4;YxgCRA4R9#~d$r$XV{^-9GyNF*15@lMze( zpW1I*dIXjiCF9YxF63n-;`Gi2{BY+ChHjq3gDYLQd+`8np6SGupk}$hQnJ33GCnZT|1aj*81J7?YIw1u0dIaD z!SJI&M1<;bbjuR-9^FDf+drK5;HNqpakzCE{@hf~fa^6f9B6I8g@c<=J1-G&M94Jr zh5#}0KY&YF?#x^mH=+n1Z>d=#9H}F;A4~{CHd#J;4>V)!rzdzj_8R?tConJDiL8W3 zl+TVuU6B(t1rAh_ske|!y&Ojv;v#~O5<_PH2k`IqHe<#7RG3K_Dr7vwalU|($WKO{;GfQ1b&`JdFRBR6d?A|b=X~?)^fb#XJ9V_wEvjP0`<+E{c zs)N7YIDrR!UAWhC5O>b)#f{S)(}Ex0@kcDmjfF-c{P%Q&=#vsmjLazY9w`YAAk@a< zArai@;{hh~-wVED%>qP)Xke9iLCIy0%xE0j6w-!`wop7=lmdG&F`cg$;r`_#zZ<-B z-C~qvSfTTwd!mZ*3N4rQ`4U9>N(Ot0upTeV#?XceB!=rqJ0{^oM-y(J-Sb)64{WZ( z+NxY6MFt|6*!g;5z0`iI$vmJt!DlrPt&qN;*8F5uK7QP=klBn~+wC7ZK@v|fAEd+(YXt_F=`4_4TtNM!$BI^Xs|~1E?h1` zo=%2V0z46XLzseCujlmpz~lg|zLM?@kp`U3h{AR*Ai}_gTFF|9F3{Avx>-~ub`0|lRJV3*8Klj-Z&(U U?%gBa9RL6T07*qoM6N<$f*UxK2mk;8 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/leveled-creature.png b/files/opencs/raster/leveled-creature.png new file mode 100644 index 0000000000000000000000000000000000000000..4aa2c56cd7bfc3407f8aa7a56830089ccc022461 GIT binary patch literal 2212 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 N002ovPDHLkV1g@2BNYGu literal 0 HcmV?d00001 diff --git a/files/opencs/raster/probe.png b/files/opencs/raster/probe.png new file mode 100644 index 0000000000000000000000000000000000000000..2e4c553279ecff5d4e7cf5d3d91984f06bc7d569 GIT binary patch literal 583 zcmV-N0=WH&P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv0005DNkl{|NlP&t+Aqlf`F%|=Rr4D z*9)#LE-R4jql@J}K0bGj9zFX1>eZ|N7c5xt-`?JS7t9efbpXicFw5`XzYli6;lqdj z7ZnxV1V&V6z+)3Y#}?{+|#Ze-9|HKr;v6v%I6D;RbMt5>i7f8f9Ya6X4+HT2YutF$G%96+|*(ZS)fzrX+6 zwQJY@U%!6+e_|~sI|R@zx3{yiO-f9ZcX4(;VPj)+!P?pyrM$;i*N_|n*es`{G9$?W z)V7?YD4>PqL_2_1mJ{UwT3Sxf0kpOpuLI~|IZg-A%W|v^pr_>+4xqQ?C=M71%TXKv zYO{lCHBiL@D%&Y3UP;jlE{Y=~BD`9fn?a4mpY*gG9s;1?4+#nRTvb^Ka>Nl*d_bvM zcx4nE6jW1MQu4nbKmWhEnHk+2fl?a=1_sW_&dU0qmYVwC#MqcFj=-pny}iBXBqk*M zkBN@{Z)jjZb4Orp54gIz&It_-{pRcA^WVtOa0;dIOje5s7zK6udU~KvqyQ})003gN VHPn4~U(x^o002ovPDHLkV1j(X_g4S_ literal 0 HcmV?d00001 diff --git a/files/opencs/raster/random-item.png b/files/opencs/raster/random-item.png index 349130abe5b47d0258e9abbbfb89acd51da39df8..0b2571422cdf1f9e396129f80a800dabef387d88 100644 GIT binary patch delta 1975 zcmV;o2T1tL49O3W85ITq0047(dh`GQ00DDSM?wIu&K&8HArpTIa7bBm000XT000XT z0n*)m`~Uy|8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^4L^m3s900%fpL_t(o zN41yPQOP0{b*IQg36d>zW%J`A=v*d4o(5;o93G|ipx+{ebbOAD>)>D*a&-dC5SIYU4 z$S@5O_5|T%Ni?or%D}9|_t>3*5S=nYAEfwrdmxX2 z|NG-}nBLySyXk-6&164bkf1Jiro+d}b;4fwq5`0A_D~5^lJ~EFfA4w$e*0%VUKtz6 zYb&MOijcrnpL{j!k2-(u?~x(P;H&;4$V9Lg6U3r3;G=QN^3}S$ z)&+=v_fR;0()n>sKA!B4>-}9!S`XoSg@jxGe+hp;F6Buy9-?0|lE1~(?hIVJl!>mE zWTp%kniA2`d;piur6TP>FeGm5u}yl_pX~``!3=Nk{;@o+IF4b9|f z#k0qC7$2#@)BBY$+^fPbw@PudF9$yqML{X!&8*S5MJyD=yaAAg)BAagC(4VWac3YO zlfQq~lCJN?>xm&ukN4x{(>_d&cH#NsHar{o5u?K=@!;C`81BzSbLDPq&?!wyDX(R| zAZ!NkS+z^wt{DFh{T+v4B!=_Kc!A9SFlL?)l9@k86qjQ3P6<(6j7LL7csN+d!0%qo z!|lttxYe73_R|SShz*3R!08G7PFsO|6###6F$qcCSVeI(<8agCO$2-c?_S;|LG;1+ zb0u!{(|P)#M`GkTaqyLupBcJ-T2q55k~pMXftEA)hG7D%S#QZRLa1`VliA@T_F;QAd`QJ zQS@Cj%9a=Yk7`LI?x`tQL#V(U1f){A%kVTt1tM-ZROlDvUySh#Gv3;}t6>r1c>q zHq(3I5CeZdbDx1vkGGSQS1@o|^TdDnzga2w(W;S=5)O^0f`RjRJa9N1Y!CNmlz$2D zX-dMyhD6jC$6&Kw1*t2$+~S1ZUakXmC*#OyRTJ=SChaeNZLosVhV%4PS<+77KV3Xx zskw(*!ob;VHe7@}oA9o>{pdIqkBZz#Xq19C^tND;F>~G)p*4-%JcidVdKiD@w&1ke zJ=~R+n&)M1w`#bQ_zeu)+1VLRPEMAzo0Xg4?NxhlwmcSzF@BJXIkha6oZt21sl9kP zR?jGZW$gM&xp~yCbY$U7^#L?hC0N1x&ZR-6aI?VqJT_BvTky7%yKs&KP(U`P%#Hnk zwa#DqgxV^d^EZ=2bHZ)SdG>#yaO~Nkvw}N1IwEX?W?pzp*-ji!4~0auYJwFS;%*q~ z&ta5Pdo?%QLMBsNw%by3bJ{7K$6bZSvN)#UzD&DWIfXZu#Gp7M6rOUvfkj5oaOYYc z>Hc=c+wE~UI_EVdaaJ`q!>bBo7KAq*k3vz}#?Jw4)T;~wJz0#s(#3zWkaDxhR2Rou zYEI$N5xzKIv(GO0>B4QuPY!`X%rUY8*GQhwTkhGZyISK3GF6A0nYK5S$wSFH-{Ruq1S2O2gnQgD#jY$Xza)+O{47va%TC4WX zTXULrs+_`49gRTB4nKd0c;5`Lq+(9w-W>tBNml5S;WC?BZ8qHOaHU7LVRuv@j%ROK z6udk$6d`^R@YxP2%r06<}KW_GvFR$iSGhP2oK zxbdBs^PLI6T_Mni2CGeN_4}>%`CQ7W$x!8H__Afo5EJHY7d(HL)P9Xx_<^K9&gv?b zt>&a`3HAIyFPR&cvcFoXvlk0ZJ5^5MOP4N1Ug}21;mmVxOL@*d9oA{w;KFsZTuD~< z0LergIiY5blAl+N<#FgFW-`}Sqb5VsPL(eNr!`OA;SVo4-?UojT=3;l^3_GeoMS3s ztxC!p+e~(M@~(fiDE%%1Ww~2$>Ua!ljzyvB`|bE4e=D=qP8^9qX?7S&$PX22ug8eN z6dc@uTyh;BCZCPp>diEqfa5Sll*}$50Sx# zJl<*-gH|mxXjMW3S+52!g}^}FjT($v!hJ}`j65y2z-AZLe*lrQqikNLH*f#|002ov JPDHLkV1g>3&0GKg literal 1612 zcmZ`(X;4#F6uyB3Lc(4G1p{F-vIPT}$j}r42}@WhV^AGn&==Nvijd%jsxGa8f0J_;jomDf%A^dQJ z&d?E(7b3I_rt(nI`NGmZaOvnWSh_0@#m6er7H!v{p_4Tc< zukY*Y16|_;g1xGS8$sZ^>=CW8jNyu7$vZbwH4g+jsO@!sCvDwWE_#Dv4)@cI1J)z$g=c{ew= z#>U2`rl#fPgty-U-tC$6c!fJ>2w~C zx45|Y`0-=tUrS5t;lqbSB5`0~prxf{aBvXXtE#GkibX|5wY9ZNOH1wT?Ik58t*xz= zmX>X8Z9r~rZtm~zhrQ(GB~jmmmw{n11YO6&`4}dn;<-{8h9%Qtz_3XH^{7r9 zCX0i@YDtaT1{p-*o9gRXxuDF3uE02ne z>wgWq!X+FC4n)NS>ku&XGD2dq;FQ%Ty^bU2u&x4OBs9=p=>5A`utv@-II9 zs^HRv9Ytgjm6esH%tI0rp2tZ&f8)}!R(l4cZMW+#B4M#k^#`fsgDwTJQhDS2 zb-$z9bi&trs{71RBn9o+(&Z%sKmGjh6N$qy@K?r;`~LicF+sNJMAFh?DN6J0RK`@r4ck3# zL}zNNgZ(#39%Znr{a$rJLc;XaJG~Ug;r-Q@F0zzM-Q9vHO4aanLa3tZkr&)c&+hI! z4Lr)s%&;S_Aj)$$&53qUbRxF+*?HyE#ZUMn4Nk;Ao$8AN1os3nJjyldIsGUKQ~2at z{F5m`RCIko98SF7p+Z4F|IFMt<=l;w)Oo){rM*M#z4;{knM%^B+*CPfZEcsMd}dcf z1t+OXcuOG>To1cqC}fJ0#c9HprZ;s%JYLqbo~w67ldW74p~l?(NDID9^`(35QNu99 z1)l4nn_8AlYi86s+{o>L@6F4n26om@+%id+rI&9c6DN)zNK*}@jpW!~9F8d7aDNwD zoqIob^{?QSbzJF&zxQhIq(e&Rl}Xiig5OG8UwCWlc%L*4&_*pjEorRR7vOh_c1pP) zN)zLyNj~DtBmm^e^zdRZy%=5|LJy`7lkLOuc4d0{FquahYD)eSkd~e(Nk0Am0gQPX w8v-oV6$I(Y(wz9rB$Shr<1RUonkA0UNODilJa+XJ#|lU&lp7IvGeD&H8)U$05dZ)H diff --git a/files/opencs/raster/repair.png b/files/opencs/raster/repair.png index a8165827790baac034005d1b4729b02ad45e5f70..5e495d8fd72c88a04aab96c5eb72ad11fb5ad9e4 100644 GIT binary patch delta 1256 zcmVN2bPDNB8b~7$DE-^4L^m3s900eJIL_t(o zN9|TePh4jdudlDgjdU{Ik?(UMStE=Sb==i6fpP%HXQb{WMpP%vd@sWJ!@Uz}tUXm9* z&&SilL-L@*@4CCWNp5twhO3K<FFtskB@P9c!-081MKbXVP|ItTU%S$*x10@ z+8S0?R>bp*i;I|_pU3R%ET*TYF*!Mj@$qqtj*en@co>6&gXr(?M^{%Df`Woz@#C{+ z@7LGYMd5$l-Ca?Xi$xIuF3hADaC>_jo12^9XZio-<>hOznVA_(O-%`~v9U3XjEo4N zfq?<^_4T2*w--G zLQ7<>SRPGCh){&DhJWu1o|%~mTN|5qG;lY74J5v5Lk9;3Exq)Chl%h1zTolk@gJ$< zUv7VkdXqUoFZS~+9335r!$ZhZeb+lDaM)N|>&@+%TM4ig6A}_oSy?Hp#n&-0F=2M# zN=r*w_I-2Ucisi0hK@qziv7z<7_4P#+9{kq(1d^YU<9}jrQi2jt@barB-_rU)%1E; zTUl+~1^mtm7>ZGpzU7?YkolU=>+9>0o}PaWit(gJA>gD?T=5`s!hIex3|?DXi?p;f z*xB0VJ~#nNF0D?d`@~nk@*5|d0lcQB2Ib}DpuqX*3+y;M$)P`hq}obhOxdya`uVSH(hNaPHn*=M2snP)19Kmk$pruU#h7 z-rf$bZI*yx4f6^$Wi?ZsGdQcpofi}ofVV7PM^;uAGBPrR8n+UluNwalT0%TbTp&L` zAGx`?$jQzYMR>8W%~DfSk)qQfDJg#miHV7bkBdWWY^>-olGZrOtqlu9XlN)j8V%I1 zULiO*7+jk%Om0K6*(qCzrEY3!LPJ9X>gwtQp{lAX@LJ{h;4X`bimtoNCW1_kEy%uCqb?q4Iv98h+!{f2W13e0umr3fsh19f+T22 z$bk?MWQ9l)2pE>2oGb^`sy%Df7VF8<_D*s1(cbm!AN}6veb@Vb?|sJ;2l$h0*Ep>U7^#B(;v@M+%+D*-d9-X=0IC#}EJUWoYJ_*W*JQ`Zl zpwhO~NaSJ;kDW?S4hZxQ2tJ(4J=JDxl2=LT%v4`r($1Ybsln8$8il^QwawU=LQlqc zWAeG|JZ?^XW38d9!!p=ovgngi60lgTgM$N+Ow3@UilxPMO*MEtrqk4+P@ZmV)~aii z3A8w4uTE!bj!ih`;^Gn=6E2kSHT7pzwF+)=UT8#M#L=*@s9;drDGn)IibzK+RO#n^p#wIYUHbY~p z;X==#VPtIJQcr7VZ=0#F!#rr{8!-=$4UFF!othr&9WwO|cTY`^Pu{++Ij^j)KclKs zsO!#Xv}aZ46w*p@NqLc=l*=v7&E;iD6=HLr(K2M#XqB9zoB}~kp_n6*6_!>A#j?Vp zk^*gW?X`)an|CH|-I*L3wHSJJJYgPRln>@vCKpO8OXO7&ae0wY!t3h4q&inAlJX@A zQAJf5=m?N(LD~m|oJsW$ged-$L%u#fBq9Otjq}1DJg{s1UKA3EL?GaBRL$Q@sT@~q+xk?@cR=0paDO$Ip}{90SEA=@RZwb|}!5J2<6dj)x3kB`~P z;GPy&RS7C3nnHQ0T6k7=3>zTw3d0BaMd7Hv5yTLG&f?|`N_5(rGJ6zlLbabZ8wIl_ z>`1f=c4ygA++O6oblHPlgQ=!c^}4o{Ceo$DXkRJ!eQZ+>1VmRobMjk`JwX3g{T{wCRd>&nOF zKiJwtud|MQbXV*ARejx^mS_`aXvFYET-;+OV)GUHz23y<#uxjtX7635%~{^rh-cPR zcsO}>{WkT;nIv;Mn7MfS8EQ0naTjf}`aXjLBM%5lbN57BDoPr*yX|*Ix$bk>yQi;K z*Vv`)Y;i2OIn~5fA^79la54P90IMH;i~s-t diff --git a/files/opencs/scalable/top-level/.directory b/files/opencs/scalable/top-level/.directory new file mode 100644 index 000000000..464bddbfc --- /dev/null +++ b/files/opencs/scalable/top-level/.directory @@ -0,0 +1,5 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2013,4,3,11,19,41 +Version=3 +ViewMode=1 diff --git a/files/opencs/scalable/top-level/gmst.svg b/files/opencs/scalable/top-level/gmst.svg new file mode 100644 index 000000000..3b59a44fe --- /dev/null +++ b/files/opencs/scalable/top-level/gmst.svg @@ -0,0 +1,1047 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/files/opencs/scalable/top-level/topic-regular.svg b/files/opencs/scalable/top-level/topic-regular.svg new file mode 100644 index 000000000..c972dfa18 --- /dev/null +++ b/files/opencs/scalable/top-level/topic-regular.svg @@ -0,0 +1,1045 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + From 03af0a8ac972ca22a4f918523cd1be2ff28579a4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 14 Apr 2013 10:02:48 +0200 Subject: [PATCH 041/213] Adding more icons from nomadic1, replacing older with recently redoned. --- files/opencs/raster/apparatus.png | Bin 1580 -> 1440 bytes files/opencs/raster/armor.png | Bin 1908 -> 1641 bytes files/opencs/raster/clothing.png | Bin 0 -> 1377 bytes files/opencs/raster/container.png | Bin 1570 -> 1526 bytes files/opencs/raster/creature.png | Bin 2506 -> 2297 bytes files/opencs/raster/door.png | Bin 1715 -> 1627 bytes files/opencs/raster/leveled-creature.png | Bin 2212 -> 2150 bytes files/opencs/raster/lockpick.png | Bin 679 -> 671 bytes files/opencs/raster/miscellaneous.png | Bin 1518 -> 1716 bytes files/opencs/raster/npc.png | Bin 0 -> 2143 bytes files/opencs/raster/potion.png | Bin 1876 -> 1582 bytes files/opencs/raster/probe.png | Bin 583 -> 587 bytes files/opencs/raster/random-item.png | Bin 1993 -> 1698 bytes files/opencs/raster/repair.png | Bin 1280 -> 1115 bytes files/opencs/raster/weapon.png | Bin 1064 -> 1003 bytes 15 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 files/opencs/raster/clothing.png create mode 100644 files/opencs/raster/npc.png diff --git a/files/opencs/raster/apparatus.png b/files/opencs/raster/apparatus.png index 037ed290fe9d5fd538bd21f9eda35f83d5048069..3cef537e140428563f908eeeb08214999255a7ae 100644 GIT binary patch delta 1333 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 mNan}{{fUIaNWNgl{r>?ZwZ|wDcoXCR0000Lx delta 1806 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/container.png b/files/opencs/raster/container.png index 7874606ab9b905dd3afc5e58b929e586241f3fd5..2a6ed01eb9969129cbf9edd6d0f404464f97cc92 100644 GIT binary patch delta 1450 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 Ys`Lns?+??S$N&HU07*qoM6N<$f>j|v?*IS* delta 2408 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 diff --git a/files/opencs/raster/door.png b/files/opencs/raster/door.png index 36ffca6d68c296cd5f33dfe9d6293c37a9de9fff..aa48858efa1e5862461f899752a2c0d91b65a2c8 100644 GIT binary patch delta 1522 zcmVh*`X>N0%ywp4izt^vAEDqqS3uWA0DB{j+R)T-P&aLSbZXfN! zjmaqHdj$B*s()u$x309Ahz$i0oSm1q4#gR`UxMG6&0ulJhutX)%0VML28<@mc)eG^ z@-`Te5wr;%9IU?~M8D!pZ)nK?mOK7Z4XTIF_^EbdL=SB`XGl9Ku#rqLzr7 z0s=P8y??jH+9fzmJK4Tb<*&lemwC(=?dWXNO7K%fD~@N)a2b^MWD7{SbdRX_Wc|vJ z2PM|udbY2Jll5=(+L3l@Fq^kvzF@)0yct1@s%9H%I#BfMMXLO>xjc>*c+8Z9nmw-v zUntqIyTgE8F@pp@kuxLCt3=rjP{Mt3yh{q2BY#Z5v7#VN`>O-D5u9u%_^zm4g3o46 zjR~N5ttQ;zyj^mk5jfdC%HSgry#$}h7|~&Gz=48SFH*w2zb}UAoDGKy_O+|FS>*(u zW3~@RI1Gn534W~0h*%>6@=O51-`g9-!K_UZLHArPoT}a#(qW|2j)5ePN=87^t$QMS z27mHiP9*rd6A>oBilkFZONJc|B_D^PPls-=4h5EcdAC+NIhO|6HVraPHM$&Xs?_*j&~<)z9$;NO2b zjP0eie_h3z4zM*U68!3DpyA4C;Er}0uy-`ERyo1HxY38Mh)JFU876?>SBCxAn`R-x zvVF6jcREx^3o4}eRwUWUckno{D~2y`4q=h5wR)d--0feRwVdJ z#fyog347RS1U?njqU=#&z^lf-m=;q}4MJvx{3vFdOeFX+d)165j2Mp_Wmit{$%qDh zu2%Fj5d^2dgQf-r5PXrnXvX6PX@9X)6K*5htMEM`HMX`XnG3BFd?Ktypb-ISr&c8R zg#qWw;*C_LD}yZyaVWvkF8*iQRYRtF)v5zmwY>@_M|}Dw`7NLaB(2t& zjOp**{||V@-3%|+fB>6T@wAgYD%Py8E*Y}EYCmg1#|AA3vldVrf`%sP7+ag3)_M{B Y0nNHJ%Amm=Y5)KL07*qoM6N<$f^E3(g8%>k delta 1611 zcmV-R2DJIx46_Z8dw&KZNkl|Rc-r7L=Ih;te1Fm*K8;G^X2dQ$2-yT# z?cd{{Qw6TmYTt=S;-l7p>E+2L3G3Y+eAMU1m0lk%_js|M^Wxkg2c}aNG`Pfs^8eVMl`EY+Gp@3f-4kMS8FjVKjdVf$+;qG`87kd2Y zua?jewc$e6i|d1aTqP1Gh(yq$d*L(dcAbk|33#o-S|;LU!@t3JqPsbC!Lt&Ub=e9q?g| zY-kNxXn#9AxRj+?2@7xXKew@o~eeWgvPH^sgwo$@#gM^EnPR!Mq5j1P_sukdb zyFM6D_WVqjUm;NnILpr9)Ae?o?{H!!Wg-Gq>VFAvyz=gI$SimHh=lKd)Bd{W1=$Op zv+Pp@K3QkSYC9!lwGjbR2?Xkh0LLpQ-04m)PIq~?S4|E01(JQD&W4Fv8_ph*F_|>N zUkZU*mmz;0zrR_J4ey z{>Xf@Q;FA|p7W{|{63>}ZO2lx4U1_jy#=f|95tacOv6aT>Ro!cMUDC`NJv6{IU_3r zcdXfgqg17UFVtHw5H%7BBaYXb(eKy7DQMIuVM5a9ms%uc+K;AX%r(i%RpW%)uX6^U zuOrZ~fk+rIUu#0Ij|k{1)Dwu?^?&)rv|U*>2Is?43iwgFetjX4NQmI?9&Z&Kr4Wb_ zfm2O3MfSo~Q``e$N%I8XuOu2Cg7`0eq&~fLuUO zNbq;JO9M$;uHJ$u5m;!jDzfuQ<-@}1R&3gfflnnwbo=$l1qDneMRYn#B!3XG>hkk6 zOdPL#Qu(ly0zMHJ(B;!1OC%=aB03xuuxrcID-gD7^T%kCIotW9j;5?{?D=k;Gx%6k zj}DJcQDGt`piM4^t*R6P7HyuNQSAHiCOcXw;kHxGODX3O(L~kg<`U@NF#+{XJ?f}x z=>=RPQ%O1u2K5S=R;diu%6}3Fgopq?quBRCwx4dX<9$xLrmdtq(O^+RhWC8u@UiDC zJ9p0DqY)i4wh{^O19B`TVu3(-7TAtC0-B|j;^);=(trsXv~dC%jS3iv=y4>h!%&F2 z4rnppuR@=%620C^8DyqtZuu)kx2O(Bzo)vo${RhGC1icE4k}LoK002ov JPDHLkV1lHH7Y+ab diff --git a/files/opencs/raster/leveled-creature.png b/files/opencs/raster/leveled-creature.png index 4aa2c56cd7bfc3407f8aa7a56830089ccc022461..ad4a7c6f837a9946e420ad59b519bb24de3eb2ff 100644 GIT binary patch delta 2049 zcmV+c2>$n^5#|t(dw&PjNklwb9kVdL*T=RMDP&hveF0P?VK=<_gm`xt6hzu<<5rC za#Pg18ur@eC1UZe=V5#&;8pJOg|XfQKAgLN4}LO+_pYDAZ?Aq2^H+xP(~CXulp7vL zy*Ax;B>ratjS=tdcPI!0sgiPyXSGRK$gvBGrV3e{C+~=d$CKGf-hDf4RD*fj{iR4~Jjex_Hih9Z)>r`c5`)mfGJlQKR=(4Ub_~#$p z#I=hjaDREY6}^cNs$CZJH$`F8X$8=DJdXPMdW6Gafr!m!gT-Qj(P$LFH5v`nYBl6? zIiv>3vE=xdv5yxsJ-VH1Jl%{A*E-<`q7cfU`kK7qH#yYZvZR!pC0ghr(l zz*DJ|0PgX4V6|GoYGebeR4Pz;Ad|@;l}aIzNPi#_iEvOX{yY|N{PC4Ub$XUMVulXa zeW6a|v2bI21N_a?O-O~^0$4*s1Cq%ksw74XCgf zKwc0|{XFoZq9PR2dh0?j9?W0CyO&3B^U^To!x-Tl!=XxB+GEiT5I>k0!L7+&ymq`1tuY^(BW^O68g_#k zI;C7VIfEAz6d*r8AAYA5orx$W`;TC>vkr-n6NAlBO!XXs%cNQ1e%)m=Xx7ftKd%g? z1n`ND8bn=Yq0Rz2dF?9mp2^gG;8lvRTw{u`>cq$Oz>N^ zPc&-vH?dd@(Vzz-U2$}_Byn@{BwnY}_caDFbFvYMcuXMH*3yi6w-HjYNC4lvcYiO$ zqGAfDlO*|8@Uuxj+(y;vwo#mMFFAUi>&(t~*{xK6JRUXMwD=bfK)QEd3(GDM}@qPR=C6C8EVd zwJSYKWy+SF!IM5S%GL7wLKkHBB!8crR!44FP`Gr_0+B%}t?X9IHe3M#i^v1y{y*^^ zRSuKRYt?@mcA9X=V?n^Gg+s6W)T)+mM6y7D!+|5zV>8aQ*7-Ryf1gc4E|cBnu%QSR zNC-hgy)G^(5mpH=?tA*4=M8@*B9AkBIF0HRK6!V<0gI;WtxZ8x?XiuYYJWSl)D{mc zIxM=ykjwJ4_izvvo$8B>7YOvrOz?2rQb~lwV>K9*$q1lCg0GnjC@d)Wh{2pj)%#}- z`!E=HvjV@{M4&F{oVzj6`|r6;Zk-uOVxlVs3JK2jzf-P%Q6`sv!|BJN^E_~FKL+L! z6c!c=oxqQa#`1>`jhzKa5MF293#mfOlrl(DH)gv z>;%sJ&ji?noB`|!Qqg78DwY_$JH*bH&u>zIKTx8T)CVeVha9F=zg4$NH#||v|C8%1 zHxHieWY3&D6Fy8JlLLHJ$x83mR_Jj&VneN+#EeuMT(2i_GrBw3NpeS8<>GuLsAj)aya5y$n?^)oi zQJt5`Xlp#{tuza=!DCJ%%1s7Aq20T8vl3r!=dW*T!X+*PD}TYV6M@B?*cJyJru0}x z46n9D5Vq@KRF?_htN?p}jG6wg36R;QS$^*SXHolA?q-yhO%8(!4w{mp!u$>Ab6WB} zT!xn>K3WL7}&?`?##~a&OX^)*ar)X zd3ud8VDm5-f(Z~1et>c8`cc1=l1A8x8as-U_*KPmqE@2qk6Lcj)>VI0RVC+FDSzL_2s^CJMNaF@QjZd^ z^xDTO^X%g#E?YdH$fE{9Nc}pDZv{MGk*~K!^Kou>D}Ma_ow#!RIlOza4;K%1;$TA= z@+{K*pkj8;MdE)Z5OvwE9BQh-&t4hAnVrpOFUiL`uYIzm$oJ1f&6T)xqzlKkR>3Wc zpZs44l(?1qKYu^74+k2`;j@}2f{NVCK$LdDZ#CcOE%W32cRLaD*ucLflbDqOdMNs& znk5$C#rWBc1up#b^lrp_j>+Wr_`cX-xi`|c3B6Sz_$}h_oCMZ-lo*Lh2<-7 z2A&VxVzGcq1EbLhtyYV)v@|C1DP{O~RbI!`vwy`tv=@3%P36tEN)wcsK_-&IW--!T zix1v9f?u9Lj&lb(aC%o08p=azR2(gXSC)iPUKBvU=Rwf#f!%I@9Qkx`7CIBi%*;f3 zdOC?OjCYRo;Kl7t7~a)_Gea%dQxiehDo%MM<6w%PO zi)&t65y94`O}KsgHnz35;nJ}lHB&#JXnzJfHe+yL7xr)OLey(VZf>p$&e1c0b^`zO zR~PX6_eb#V_jcg*eI0m-$ak;JgHII3A1l&rHeU71#!tc)0|I6Nc_!h3D4HIz$Vwvx z*wa~yZLN*CaJ(NUXo23%Wq7%NGa70)sKnY^TTmDAz@XD&_3G6scvfZx-aEY)zkj*> z0^U5h4I?`maJ;h`dmGoH$tS~Y)Wzqt;)HrhP@^m=MNtsU_afkR!RxXk-{XM8W>M2# zAN8ZLt_Gz+KWvf-85tQ^xpF0zELnm)*@R0+yK(+-*9`EkQZGtnEo=te=)8LYk-1L7 znlg~#u*#DKM?DXVNubCzShZ>umVYi?idCtp$j#2aRqT+bdZKyQTVJe}_PKJO8hN3p zg<{a%RJ&k$PjcimI+D#o(Ca((dcA5iT;DZo)~G7y!R^KobIMZ*m<0GJJ3IRtuR+%9 z%rhH5E|84~$p&~u0ZyatV*-C{$tnRh2ewe!Hec?kDS^{$`t5WQ^w*U{DSz1Uh>&VH zxukXtiH`c69T3x7kV+9xtl=^V6Fp@k7~t4jAzb9dRp3L1|tI3wubE3 z8d5j|zn(#$&|!W1RDUCW@_*_cT&Dhhska`x>xw}yL9f&OgT`kx9x?Efz=CtSwZPJx|*?$->amj!2$;O8U zZLXS124{Esy0oiX@>k%j0q%qZiG>Rn!eY>$4M}=DQ|v-W)W9KVW3vd%byOlz?VvGE z0{c77UvQn1Yn}|wk*l>Q7v#=ZuwVf^Cf(GQpbfPi5jH_LHt&guA0W{kqPkD9x;YD+ z0Upx@mjL(MWYiQ=e}AtHKsJ1-0Vc6%(IN<$X=sZ$(BP*7i=e%05pAExqUXpb=K`N)LS67+wfUB%p}0qdo2(&U+#uXU`Mp#Dbm& z9Q6<#IxE~VM2em@z!~6qb$a^Le@%dtKg@eO*PDsZ^}Xc9?4q&BZXj_AI_Pq9)TlEE zm^&ar%bM3RpSg0droNC!*xKkLIl~1X^o0FYA$zH%&Sg~RS z8&UL0Bxdb~+;$0L;iDDre4GKcRsx%`k?_KlnX3fKn)rx@lb#!AGO8ibnC~NJ76D5A zLk4CdJQCL&5fPa6VUZji5x%p0`Eqr8rsx0m)Fq&oVmbU_LEG$y6kVL6W7Wq=h#ygk q_46%A&qe5+4{4pd$=?8Tz55@NYw_ktWMjYp0000e)Lu4Zl9wqdTDmADB8rN-_> z&=&|iNgaCu&mM#>o<#^f>OsYWh+t?ENhoNF@U;C@p%{McS1pqAT zdM+g?>Jo&a;B*!}9#0gxYr{oRyt@sBM(uVR8jS{A`Te6)QGblCCBO{tbUNyw0cy1x zWHK2zWZ5G1061Q+*QaDQJp#V46*F80Wq<7TX_Y744$8)(H zI8RPK7>2Qv;D#!o#mD0@Ae?2{{wlcc09t%F96~mm1@#}zyP_zYq$8jGZs`=@cq)|w zK@e)&TU#5e;!7*A2;a5YUd_V)44}ok-7X}PNmTZVnSc1N0dPE#NPxrP$eK}d{2M=d z0LLHh?_tkwf2M)|sDKu4wOW91wc(y<;okyi@n*9L@pyb7dA*M`@p%9oN0)|Uo;P%; zkOsBjHx^lzKi7p%D{$s^zoDB-xm*VI>eN$YndndH5M8bhb#Es=REPrv w0)dw!jwkE?2R@yG9jo;<91gF1sE}6R3taM#(lq2t-T(jq07*qoM6N<$f>S624FCWD delta 566 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 delta 1773 zcmVauk_J%ZmSs5? z*aciz(B+6AA}W`lBF4(02~iHADi99QfI;Mnpj3(|5d;OKfCezAfGC0k!s1b@rqy&l zeU}an1d+o@|9EEinR(ym`+2^<<9XhBz`VH(x#9d2N2B>Y)_*$h^jT@Y6F-+V)bGqm zT>YYt#hYZf&tt!09*(+i_5NP~OeJ<^dWNEhR(8%RJCQD7E6fQ|m>|~G#7wGC=@^I} z8e7QBW&<-T2ON~%`97OI=j*DQM6Gh9B_o{b{h@eDjY%r+!aXnw3kTP%UkpIKu%(@I zZDi_kKJ&1nIe%|2HCeH^N(|Vt?--`GirU$T&p8LYLUyuBZpEJMAw+KpKyGc0Ye1B+ z-s}^4Rv{P@SQ)%S2*Vxfy5L+Vq@3vBV6>oOydX#u2)m8aKk+e1cW4~2CqzH58VxejQ&0d0NIatqD~^P)?T zeeoFyrv`{D=)fgt7bbRYr>ApcN`Ma*EO^sMY;`v}>kRql2e^3kKV0jF!3Qw>59l9( zjyupQw0|J=XcB;`1vk_n84W+Nv*Z@O@h8wWGQX={YbuZ_0W4&St7`G$`XSo7K_!Sj zd;;Br!tRCn>2@ejc&%NOvsal>uxjc^QqgSQ`_$IT3B=JV}eB@5dLM8FuDeNm9 z8h-`YS@8(>*m86&ol1Z1!XyAE&p=h~(aSV$${UTjs-TsBMO4zYI-4@H?UZiHrJ}t5 zMGh2KsyO7ANxHT#$0bo*Sf0!&yBIPJg4nS@L6jnzsE{1|S0`g`>vjK?03u5}v#-1p zXpqHmH@6v;>N(GkU*o5WP9CS#GqUw0b$^OP3XC>#aPeBwwR||Jvz`-@NG`gj(jJ;a zXG}ir5!qZ294NKfC4dAI|H&#s-<6^?UBjZK))P+42@Xi)?(rqAdl}yFEe|^$Fw*mw z=VjMM#h)B+HgVE*O3@W74_Xt0%K1`cWHdi+0&=p%mS9}3Yfd^>XkU?uiCV!W< zrBdUYNSWeG619Bs(o&*h=`!K+G6BHUMqYSg4f6)}9bGL{OrX!bAm z$5Z=L7MaKj$A@78fUS#n%_(s>gMUFq^tarjzqoT$d?2KRzQ7`S{POAYJ4)xqd^$Gd z((0ehrL~8sQ>IYmwC{y@sm*SVS$;u**$$3~!pSz;MuO%#JbtT(jn|lKaALqeORHPL`(Dv2Y)Oa+~N;A z?c(OTBV4Z<RX1m?Kpw20QuIx4%+MdxZ z44KVql^aj@6d-#PaDo zq0p}vtg-idnynW=yI&qB%kEJbS3j$S8!sOB(RviW*2YNJ@#&1t0<}ekmJWqq+JsRc z4x?dx-fM|_|K1F%KiZ+OR63#l$3ijXeZW{Gy%oLGU#Q{W8JF76cYm%Hw|-lUrjCVh zZ<@t@K>e`VE(1f$p$L6nl7)k&Toyap;a=8c)O9{yeD}gNc>Yc_Dz2ezGBl?f(F+KP zbK_dEFX8XY1(0>*inmYbaO1^eK3pS|n+*A{gip0U*`q0TYsjB|G<6D{?m{|afU$)Z z8{7CTFwo0LbSs%fEmB{{QFCpZ`ysIPt%@sOSbz&H&^H znmGWQE`M+h$mj5X!DR+SK3N&*7KFcRenDF1u)|PfrK!1wmR1X1CEvKpj$g!Mi z4j|WZsyKiW%PDpM%<|*MkN*c{u@4_UfN4-xLr?9vN?Wqa0c6YF-P}G$gonS~x^*i_ zmXjR<=#~SER@>a%TzM}~&l8Rg4j1h0>`=;ke02@UA%M+tN-8sw96)W$Ns0nmSWdJ9 zXk|H34xpvw1b-bsYs>LEfF73PbO609$LaujT8`lWdRva-fPt_a#Q~r;JE&FzRV<*g zos!~}6usc0I3+pRYx?x*|LyGTe$vx&cnE-kKQ1=*b5~avsKt7O6dzEk7G4>}#>CXL zG&ldRt*QBMWobz_N1)V(k&%&e%F4?A7v$&vH#0S*i&7&ns$*a$a!zJO#{Z*7ks>r{|ogsHkrN0RjJwjf|#H8qZ|4h)hjP>J0St?}8F2Egb*=2f$1v^&Q5X P00000NkvXXu0mjf+^gwo delta 469 zcmV;`0V@8>1jhuBe1En{L_t(oM`QT^|33q*v7&;4fTySDK{r>|3$89ME0FD@i{(B( zK6j2DJ^KIZ)vNy(ELia0-rjx}%n>wo0LbSs%kSU64|c%e!-xMD6&2kD${BzhK{E$n zvm6u(n>TO%pAa8^4=ArdGY8mYRR@q`In^9MuH{s5 z040`F>;RbMt5>i7f8f9Ya6X4+HT2YutF$G%96+|*(ZS)fzrX+6wQJY@U%!6+e_|~s zI|R@zx3{yiO-f9ZcX4(;VPj)+!P?pyrM$;i*N_|n*es`{G9$?W)V7?YD4>PqL_2_1 zmJ{UwT3Sxf0e`f%9IpfDVL46*(93eH4xp#y7!IJf)F93BFo;13B2`CL_5339{{QhY$ET6kp?928VjT2k`A zAV2@VxtST=9D!0B1_lPs$azwj{a|GU_f(6 zU~Lb$y1LE@4GsO~>*Mp^$k1>KrSVKwiwGD6b^3aGpiZO!Egb*=Vzf2XeRp5d00000 LNkvXXu0mjfS=8OE diff --git a/files/opencs/raster/random-item.png b/files/opencs/raster/random-item.png index 0b2571422cdf1f9e396129f80a800dabef387d88..7b8e68e60543867519ed7518d0061c8a21be3b60 100644 GIT binary patch delta 1594 zcmV-A2F3Zw526i_dw&KINklc2^rkbttJT4Abfl385<)_Ngb+x= z5)#8=2_T>#P(VZ~;BJvBt;L0cD6$q2M5z=gRZyxFMX0qbiW&mQCKgaD;B=mz@64PG zArO)aF21XioZs_q&wIX)0DNT0`FzzXfvdny8mJamM@Rakl7Ihdf+W`AA+jcarKmMH z(0xSi$!jq8ofg4EgQaz)mr{_E9fxsUHLAF+7Vc>fjLuFrtNOVGR` z0>U)Xk-4`I@!?%B{+k)a?DP{%k2d1X*gd>^-Hlhe8U(0BIx0&auZV!He!}L5_s-$p z*Ufl4eiQ!;Re#d(>9IB%o=0UyQ3*(73UB9OUGGIq43uJATa3}?g&6KD zz)YtmO!mI6`mi3}+kO_M7m^U{@ASut3!t*FD!}K{4@Z-&5E0Dz z;48D63kk5Fjn#YxrQ{P(&smm;u&4y&#ZrkQFF+}Hy?-;zV@|DbnDdp{&Z>Pmv!Ox4 zIfa}ziayNnvSTD*K(hQXc^=(>t9&|Qu{f6s=m+-Wi-(A~pa z5oTq8G@qZhbJyj<6if`(V``)w6T06p{-Ob6)ERwNkD;C_^mUv^SL-S4itw886g#Aw zBVt(r{(mZwdaJ^9^6&e3m>j-Koi?iZuA={O9-cq?5q+KK@TC0=dhTb_@W*$*!=pPV zabR!Ydxeajznln@0s_@;`FrBG&P)u{P_y1a&3y}oo)j+&?`%GShc`2E;$R2_j_ejw zB9;^&7IIoH<|I%NH{s3rBfRRbr|Nv3hPO3k;eT*?I0Dsj@OV6^m7Yk9^~bI2hrqxe zG-jZ!;TX#E;-Qf9JC<_CMFn_C`3;2npZdee4L89orVwhl^I076x`0v z4u7_`ws7Ryg%X}FXmjX~s6 z4_6#b3xz~1py6yb8=E$5!p<-+I&ucyRF#IC75h-06APi!=Fa&&VIV-Q6!tLvf`2!br=X!U8BrR^jKI-GZ&rE%6kL7bY&^AI zAJ8VlG~E1Aa}&AfYo2v%he5-oB?Z!OYinz4+_;fWI}3wi;b zVs6_&&t*)$ytgQv%=w+#W2h`jK}Eq{19;Q5gK%+n(8D*gS&PDN6egnPVgiB`&VM~j z8T108!o3E`sExh2ZuXoXKM;o9F)9Q2h7B7K8YrP_K0k5>el7niC}q4sBLPWqDlM_s zf$k!c4#&)SX>Ovv=1kfNoNe<3DyZ3C3VxL;!8V0JYb0QItWrz7-ITq~H<{v`c!QcV z@WLOWO~Na4b|J`j5dn!YO6};g+J7azeWAk@o{iJjoWP^Q({SGPG*Ez@bc^(2=L|`mw@`v=zQ_lC2FPS8Em!1 z;KXEptw=?Hp9o%_PEh%{pytwUdd|tH&2KnTbCPxvIf0j*iiDdJyVa-%WPcLJ^s3^o z@w~G@zfzZiGY*$~at9K3`rvHFcC+CpQq)9%eogDgka%>|cKP(v2f6e(f0SvK;LtZ=BL-0AuIz`%eZ`}wSSvQc;3-q@U~bR-5ZS7 zF-ea^Xy2K6Kx4F07kWEMJBfTbIEh@yvoTu5CNCx;XS)cwgxi;zphEGP7?a+*PT^4;2&94!;ho%oJr@xP2FjOtnYSgaUU^5kUlrGvY{hYPL sUWvmIlOc0XMoq-GsdlupHhE9@AL3)&a$Qp|g8%>k07*qoM6N<$f{UXW8UO$Q delta 1891 zcmV-p2b}n#4apCXdw&NwNkl@9t3Xn!<5TQV@Sp;NhQ4m>_0@RU4QCzXLr6a@OP0{b*IQg36d>zW%76Hg^t0q|f6%R!p9%Dp z^tvmB4|D-Cqt;WDWzYB84OhzflE^R(67~e)WJxrxUdq71#9$EU1N}O=v9=->z3pje zYuJZ`UF)Fr_+JMg;}2dupNa`XHJ*=F;q6ot#vfJSdjApJ8!W)YXeGu*P9W#-CMcx5 zE_>9|_t>3*5PzLALLa2~czYm^f&csCbC}-V#k=W$;LT(|UXY+Jcc#O~%XPwD_@V-! zZ}w0LQ&0f71DJO+KFNkL&$iOj-}&dxeBs|9=TU zF6Buy9-?0|lE1~(?hIVJl!>mEWTp%kniA2`d;piur6TP>FeGm5u}yl_pX~``!3J1!PEPdFx;!cFSkl@vo8lf6h%QPxm&ukN4x{(>_d&cH#NsHar{o5u?K= z@!;C`81BzSbLDPq&?!wyDX(R|AZ!NkS+z^wu74Q+5B(j7VI+q0%6Ngy|1f5r50aTb zM--Q0^iBy;U5rOVMR+(^$iVMj&BN`>xwzGvgZ9%2NQe!DtH9|A{Z3nfd=&t3F$qcC zSVeI(<8agCO$2-c?_S;|LG;1+b0u!{HYXuJeG?7ht(QuuogIW#0PEMvwZz+}J6n=4_OKi?6W#dNs}V-|#Aq{Pwbdu~ z!^=wzsZ`3q#bPmBU0op(i6E1TQS@Cj%RV(}wf(R9Vta;XhqGVyU@@TEf8DY&KkkJe%;Yy8Y-l6_1MCNNALTH}tk( zkuh`L7NIqb+&qTYFM1f|w&1keJ=~R+n&)M1w`#bQ_zeu)+1VLRPEMAzo0Xg4?Nxhl zwmcSzF@BJXIkha6oZt21sl9kPR)5bZe`W0YO1XK|u5@JKO!WaYRV7%#`_837rEs&r z`8+mLb6fDXle=(^1W-UWr_7E0fVIwF`h?mlo%1)7LvzAy&3X2raO~Nkvw}N1IwEX? zW?pzp*-ji!4~0auYJwFS;%*q~&ta5Pdo?%QLMBsNw%by3bJ{7K$6bZSvVS|YH^Zw6V-|!r9*;s%+Q!cT zY}Bg^13g)cz0$?9kaDxhR2RouYEI$N5xzKIv(GO0>B4QuPY!`X%rUY8*GQhwTkhG< zrc;5`Lq+(9w-W>tBNml5S z;WC?BZ8qHOaHU7LVRuv@j%ROK6udk$6d`^R@YxP2%r0&a`3HAIyFPR&cvcFoXvlk0ZJ5^5MOP4N1Ug}21 z;mmVxOL@*d9oA{w;D5q(v|LG6_W;R6966z8j*_2OjpcFZBxW+#R--0E(@vEy1gAAm z-Qf=}Ip4He=v?sSQS#MA#GGR)VXaEa8{15Fck-^aDE%%1Ww~2$>Ua!ljzyvB`|bE4 ze=D=qP8^9qX?7S&$PX22ug8eN6dc@uTyh;BCZCPp>diEqfL!A+MU?C3y@+Q2ldemp zgquaO(m`Ht`Fgn;Je30D8V`}dhdkbD7lT$UG-y>q16i*IFNMHB-HjTITEcxu$BaBJ dw!miAe*lrQqikNLH*f#|002ovPDHLkV1i|owQ>Le diff --git a/files/opencs/raster/repair.png b/files/opencs/raster/repair.png index 5e495d8fd72c88a04aab96c5eb72ad11fb5ad9e4..6cf1c0aacd2fbb94db16cdf30f0008d8c69e08db 100644 GIT binary patch delta 1036 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 P00000NkvXXu0mjf{DwyH diff --git a/files/opencs/raster/weapon.png b/files/opencs/raster/weapon.png index b68878a54abbadce500135ea0dd77e7e53168118..3d4b534661076843ba4db3fa81c056d44e108cb2 100644 GIT binary patch delta 892 zcmV-?1B3ji226mGcx(sEIm65g?=zpA60SIm~nZWDy!pzJJsH&^C zn(J|D)U2-?;f}5dFb>laY~dZa2Lj>K)6-zJTA@-d-)c~c!2F^P#-FRepy30?PV-L( zEeTvusfM;Y_rWJ7CSYuA3@Qj>t5%T@Z~Nt7d`wVtAGjy>oj_A#WB=&rs6X~VxY1~Y z-riow$$#dqT(8C8Wp^p?ILGaQW!RShGTyrgzOk_Zv$L}h46fJffy?1gbthem$*Tt~ zs{;$baojL6GUDAUJlvl)q6859+2G(hUGRt&5rW_D==dEDUQ%2<6wdYb=X*+EuW*7O z`XhnwDFK~UD+}jb+tT7G6bkP~3J)s)!P{C}$$tgs4cYC@&CS1fJf2}c@LdIn3JWnG z+~IHp9kufE^7VtjLkd7}GFBIIJ~uZPHF!_~2u^OfZ?S;y5P;y4ii$Ol#}m@IQlaox zDV4JQ);#1U{2y?C0yo;*8RVbs`)$bMJwzC~g8kO*MPy}%<;wSyJmZstM`E*dSB;<&=YZ3vchrGk4 zfJgJ68{u|#p?|&62$fu5CvZM5`JYL{gT=^)Hai(SPU31x@)1=~Ae#bA&36s>`Sl^@ zJ~iV(offj})V2FHC(wB_12x7(q;d`~Z-ld&0J$t*Df?4%QG+iZ?qS;AfQB1ND05OH zI%hornN(`;>gqy8dHH&kS%s;$x8ZnGi(8ka$U4bg3x9XcssIANQ(uqS*;yC^wAbfgy8Y?R+n3+3^dp>e%PE5SfVF`hRY19Km~ zC-$5GO@Gr*qrrQ7d(qzB4y)A)iCFZRv#?hB4ku>fFzO4YILZONUS11(z{lKFN zAn;O}c5UaJ4R}NW1kSA3-|>KN5kTO~@sfS+cDoU&=BL$aA2St}z1BSHCJe&KhlF%` zJb&P!1TIxo9n)#Go*>-o^=|3*e3i;2&d3P;%dwUKfs>j?gSWM{K`xX1J_vXqfdZY* zF*rCFh&|kSOG^uwG4mc2JRpFgsCT2IqwshMl+*1##W Date: Tue, 14 May 2013 17:57:35 +0200 Subject: [PATCH 042/213] New icons from nomadic1 finally. Including dialogue-greetings AKA Ave Caesar icon. --- files/opencs/raster/body-part.png | Bin 0 -> 1359 bytes files/opencs/raster/dialogoue-info.png | Bin 0 -> 1851 bytes files/opencs/raster/dialogoue-journal.png | Bin 0 -> 1991 bytes files/opencs/raster/dialogoue-regular.png | Bin 0 -> 1486 bytes files/opencs/raster/dialogue-greeting.png | Bin 0 -> 1948 bytes files/opencs/raster/dialogue-persuasion.png | Bin 0 -> 1987 bytes files/opencs/raster/dialogue-speech.png | Bin 0 -> 1987 bytes files/opencs/raster/ikony/.directory | 5 +++++ files/opencs/raster/ikony/Hand-16.png | Bin 0 -> 627 bytes files/opencs/raster/ikony/Hand-22.png | Bin 0 -> 824 bytes files/opencs/raster/ikony/Hand-64.png | Bin 0 -> 3036 bytes files/opencs/raster/ikony/Journal-16.png | Bin 0 -> 741 bytes files/opencs/raster/ikony/Journal-22.png | Bin 0 -> 1087 bytes files/opencs/raster/ikony/Journal-32.png | Bin 0 -> 1823 bytes files/opencs/raster/ikony/Journal-64.png | Bin 0 -> 3891 bytes files/opencs/raster/ikony/LetterA-16.png | Bin 0 -> 631 bytes files/opencs/raster/ikony/LetterA-22.png | Bin 0 -> 859 bytes files/opencs/raster/ikony/LetterA-32.png | Bin 0 -> 1414 bytes files/opencs/raster/ikony/LetterA-64.png | Bin 0 -> 3370 bytes files/opencs/raster/ikony/Mask-16.png | Bin 0 -> 822 bytes files/opencs/raster/ikony/Mask-22.png | Bin 0 -> 1200 bytes files/opencs/raster/ikony/Mask-32.png | Bin 0 -> 2122 bytes files/opencs/raster/ikony/Mask-64.png | Bin 0 -> 4461 bytes files/opencs/raster/ikony/MusicNote-16.png | Bin 0 -> 507 bytes files/opencs/raster/ikony/MusicNote-22.png | Bin 0 -> 665 bytes files/opencs/raster/ikony/MusicNote-64.png | Bin 0 -> 2340 bytes files/opencs/raster/ikony/MusicNote2-16.png | Bin 0 -> 1023 bytes files/opencs/raster/ikony/MusicNote2-22.png | Bin 0 -> 1201 bytes files/opencs/raster/ikony/MusicNote2-32.png | Bin 0 -> 1868 bytes files/opencs/raster/ikony/MusicNote2-64.png | Bin 0 -> 3265 bytes files/opencs/raster/ikony/SpeechBubble-16.png | Bin 0 -> 657 bytes files/opencs/raster/ikony/SpeechBubble-22.png | Bin 0 -> 885 bytes files/opencs/raster/ikony/SpeechBubble-64.png | Bin 0 -> 2967 bytes .../opencs/raster/ikony/SpeechBubbleHand-16.png | Bin 0 -> 845 bytes .../opencs/raster/ikony/SpeechBubbleHand-22.png | Bin 0 -> 1198 bytes .../opencs/raster/ikony/SpeechBubbleHand-64.png | Bin 0 -> 4800 bytes .../raster/ikony/SpeechBubbleJournal-16.png | Bin 0 -> 849 bytes .../raster/ikony/SpeechBubbleJournal-22.png | Bin 0 -> 1189 bytes .../raster/ikony/SpeechBubbleJournal-64.png | Bin 0 -> 4541 bytes .../raster/ikony/SpeechBubbleLetterA-16.png | Bin 0 -> 839 bytes .../raster/ikony/SpeechBubbleLetterA-22.png | Bin 0 -> 1164 bytes .../raster/ikony/SpeechBubbleLetterA-64.png | Bin 0 -> 4123 bytes .../opencs/raster/ikony/SpeechBubbleMask-16.png | Bin 0 -> 885 bytes .../opencs/raster/ikony/SpeechBubbleMask-22.png | Bin 0 -> 1288 bytes .../opencs/raster/ikony/SpeechBubbleMask-64.png | Bin 0 -> 4685 bytes .../opencs/raster/ikony/SpeechBubbleNote-16.png | Bin 0 -> 810 bytes .../opencs/raster/ikony/SpeechBubbleNote-22.png | Bin 0 -> 1152 bytes .../opencs/raster/ikony/SpeechBubbleNote-64.png | Bin 0 -> 4646 bytes files/opencs/raster/sound.png | Bin 0 -> 1144 bytes files/opencs/raster/soundgen.png | Bin 0 -> 2041 bytes 50 files changed, 5 insertions(+) create mode 100644 files/opencs/raster/body-part.png create mode 100644 files/opencs/raster/dialogoue-info.png create mode 100644 files/opencs/raster/dialogoue-journal.png create mode 100644 files/opencs/raster/dialogoue-regular.png create mode 100644 files/opencs/raster/dialogue-greeting.png create mode 100644 files/opencs/raster/dialogue-persuasion.png create mode 100644 files/opencs/raster/dialogue-speech.png create mode 100644 files/opencs/raster/ikony/.directory create mode 100644 files/opencs/raster/ikony/Hand-16.png create mode 100644 files/opencs/raster/ikony/Hand-22.png create mode 100644 files/opencs/raster/ikony/Hand-64.png create mode 100644 files/opencs/raster/ikony/Journal-16.png create mode 100644 files/opencs/raster/ikony/Journal-22.png create mode 100644 files/opencs/raster/ikony/Journal-32.png create mode 100644 files/opencs/raster/ikony/Journal-64.png create mode 100644 files/opencs/raster/ikony/LetterA-16.png create mode 100644 files/opencs/raster/ikony/LetterA-22.png create mode 100644 files/opencs/raster/ikony/LetterA-32.png create mode 100644 files/opencs/raster/ikony/LetterA-64.png create mode 100644 files/opencs/raster/ikony/Mask-16.png create mode 100644 files/opencs/raster/ikony/Mask-22.png create mode 100644 files/opencs/raster/ikony/Mask-32.png create mode 100644 files/opencs/raster/ikony/Mask-64.png create mode 100644 files/opencs/raster/ikony/MusicNote-16.png create mode 100644 files/opencs/raster/ikony/MusicNote-22.png create mode 100644 files/opencs/raster/ikony/MusicNote-64.png create mode 100644 files/opencs/raster/ikony/MusicNote2-16.png create mode 100644 files/opencs/raster/ikony/MusicNote2-22.png create mode 100644 files/opencs/raster/ikony/MusicNote2-32.png create mode 100644 files/opencs/raster/ikony/MusicNote2-64.png create mode 100644 files/opencs/raster/ikony/SpeechBubble-16.png create mode 100644 files/opencs/raster/ikony/SpeechBubble-22.png create mode 100644 files/opencs/raster/ikony/SpeechBubble-64.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleHand-16.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleHand-22.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleHand-64.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleJournal-16.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleJournal-22.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleJournal-64.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleLetterA-16.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleLetterA-22.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleLetterA-64.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleMask-16.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleMask-22.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleMask-64.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleNote-16.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleNote-22.png create mode 100644 files/opencs/raster/ikony/SpeechBubbleNote-64.png create mode 100644 files/opencs/raster/sound.png create mode 100644 files/opencs/raster/soundgen.png diff --git a/files/opencs/raster/body-part.png b/files/opencs/raster/body-part.png new file mode 100644 index 0000000000000000000000000000000000000000..333c5d5232ad50c35c3a124fea530370f84e61a1 GIT binary patch literal 1359 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/dialogoue-journal.png b/files/opencs/raster/dialogoue-journal.png new file mode 100644 index 0000000000000000000000000000000000000000..b6a95c53848b787d5e857c1f8c3a38238e2518e6 GIT binary patch literal 1991 zcmV;&2RQhNP)N2bPDNB8 zb~7$DE-^4L^m3s900%=!L_t(oN3B;2P?XmhT~V3EA(pZ)c9-R`AS{ALC4eZ18j25$ zAP+^FSG)0rC=o+cY;hn-#W7)qh^BG0c4BLVNmFZs5{r#d9wIMAP*_lqS3m_M3Kqeh ze)l#%*+mekGV>4YaQ}PGJ>R+C`Bo%)h93(H3lEu08sqQhduYu&Z{{Z_?`TR(`{==e z10UnlPxtii-ksFBZCjinA|fQmP3N+E^5n@YCQO(hd4{b=UNV0CcngJG9{=VWQ8zL( z|A5BEtLW%xKzDa5?%%(I2M_Mj)4~7l?ruY8XA|1mYSGYe1$lX=@ZpC$2YkF=`Mag1 zWx$w;Oqw*wCwg^6b$R)D+`HF=-rg?s_x~FYA9mB{R@}aQ6W@PdjppVm+`4szo(fK| zx%oPgsN?@{ZLNX9a0#FPJ`K~SdmJT2UK*8%nVH!*jjcNQvjd+Dbagf2(W71he#lSQ z-fo~xuc4)-ihwH7)O3}DH#A&EeSJA@-Yi31T?uMyi#f2tP)wvM`BPZ<4OWCMyGd$z zj!1&Q$GcB;`%_-tX_B=a0|Wi|;Rgm>L#L{SkFyrb0#!&{C&hv}wpik+L4>O#!d)E@ z=Hh_)(=`a1t3phK6mvb*sII<ZU)}j zd20}yojgjXMcQwza4g*t(SB-VcxaIBZi}?3w%F^YMygJQ=-EpAZLc}jhDry)D=YJG z_38yq;L4TnkdUy6k(g~lLSk*L&(6+7PfrJdKO(c$n}9RfSLqy~kCG39Cj=<5X{iDm z7b~zKNP%^M3anWu$KqKk1pC==Kmoj>;yf;2K8N!1Z&6x$77^jgo5>SD<0Q!KmhZ-G z=axe1z>Ev7em55%T#Fw9lQI#dahHwd@{T0~aq{RFgs$s#) z%KpU(kez{-l;lDHFDm+mRQN08GT9Chb+zW6o=$$%nA=CX zY7yl0SBZdNI0l~LqC{+{1cwvFc-Ke9!Q-`Z1Zp)V;7oR7@QW97P*89RUS6|Ki1ugf zeZ(5f-MjTqz31VKfYzS7T>#%TMTwZ#B=|f*j7{D$4j$(yqjef?xS_JMlMCSa`Pm3r zzNDBD=>M1u5KG1hxZIrs*9 zDdszBxZ9rwe&NDD;N$IiQnWfMJh!9c7Vg}s=k0YkaMoT|I8(PH0>`mAXT3d?2n0CV;eBT%f_-fe;$y>W zu3u!0;5l-yYb1-ojU<4`)zY`bJ-vP7Q@p#+_MS_a>xgjJXV?P?BqhKEhhq-S6X4$Tb5Wn zo$mjSh7)9G;DI^?b}lu?vY8To&xgv+z_-1>xsSpq@QFku66U}D)h`>Ho3BwnFqnX| zV410Pz&uYCUJsPQ+e3{xIyHAYGaReAr?VP9Q&k*%#uW9i;P1T`+eg6{HR4RLZtdIk zEiKo1DU9=cxKtCG%xG?BhGULjwQ@xpoqYaNry{-njk>0$Dn3qKzh3x6q_X~Q+~J0T z4`;ZHeW{o=^X0Fp=F(9|GRo=VhK362h}HiWIIBA|-09QDk&?U}ety2+Sy@?yj0!9) zm_6I;L~U&eFM+Y_Wo6%j#_>DhVXsy0OpG7M$k>A~zSxhf%tQFgv4c2xFb#WBldv&H ze}A6;oHLYi+vtu@d1hc?p8oxlBI?z1-n2p&?0hZ^i&Kg_WkDqJfvAnEvbvcrse~P+b2{+uy zlYa))arIdCc&@c1rFB$PSc@>l9zFUQ>)8vRYtym5%*N)_)TD=OrpwAY%oKQbCyy0u zr1g{!u}6;V!`ZW6F#>TfYTq&Kqf#k%rKkVyKhvhU9~;w)FLLqE$$<2gt&wHLi`-Y( Z>%YE4D0;;cY#smr002ovPDHLkV1jGJ%=rKS literal 0 HcmV?d00001 diff --git a/files/opencs/raster/dialogoue-regular.png b/files/opencs/raster/dialogoue-regular.png new file mode 100644 index 0000000000000000000000000000000000000000..f9b8d252d368f16aad97beabd89aee50a53a6760 GIT binary patch literal 1486 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 Vb_lquM&tkh002ovPDHLkV1n32&YS=M literal 0 HcmV?d00001 diff --git a/files/opencs/raster/dialogue-speech.png b/files/opencs/raster/dialogue-speech.png new file mode 100644 index 0000000000000000000000000000000000000000..11eb9f1ca8163670aab67bb916490c145ccf9340 GIT binary patch literal 1987 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/Journal-32.png b/files/opencs/raster/ikony/Journal-32.png new file mode 100644 index 0000000000000000000000000000000000000000..6c24494166bb710bf1213dfc1eeaa3d788f04b31 GIT binary patch literal 1823 zcmV+)2jKXLP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000J#NklN%XY zlwK%z+R~O%3Z>jHB2b`QLg%FgM-i%(BcabIY=; zGbUs+iys$1?8BCg$+Q3e#5M@@lw=?NX~LJ^^Stl#zVCqnz<8fktGQPbt(kP?g<^9j zhfN(EHnwr-ZROD8;gFpghCGvUsxnGFSwWsFN+rDVNY!N7(^pD4Vch+9Na*@0K{w>XPB#Uu1als0ow5HRA7wb@=K=6&iB1 zxLjz*#ex)!Rl0yq#{s@iZfj*$rsSP~q++Jtl7I@Zh~z+#ip^ z*C!dIn-qVD3bgp9v$L{C)%H_6MUjO@U#(5(jlk4C%r!NZx_?Fzkz0U~ilPyU81f zRp9m5Q1r)y;x+Pi#>lZFT8<+f@Zs`8xQT$j9wgw;M;HDVd^-`a zHA;qRs~jUcf^cV;2r!DYAeCg`=CUPdDV1UDSUCFJ>9d@>Z3^sIEy4Cx5^U?1U~8uY zeeDu#X_H`6s{|X}67)7p(9o3TXW-jBFJp~ShCWhy>f8(OAp$m#XVR!1 z`kjJQt$JeIm4k{%HBO}&aMhU^FmMf7GN1Er&M<;=fAIBM9%hYdLR0{C?IHqB+VvPM z&Ip+Hwp?B)JB8CZ?=EBKbWY*x0trYV6}U!RQvoMZb-1+D5pdKzIlK=}N3F}r&MLbX zzBW8S1*m{4#p!~8<0^PDx98L0ug*unW#XC&IA)8(`TP{o zB}3=joz45;bj~}9S-`%RHJmYN`(RDWHq>xILvSo0sD+v9I@#|;WX{_X}sW^!mn><(3HyxY4`SgI^3h2hk&>2 zMnS+HgI4&eq4!*Dx7XQuAAG!zL2askcuODw$)p8GQw)ND-G*=+N{SPO)3mQhCauU;!0mRI7WXd)YKdfMAd z79rnEMzsD#)a9`Ag6GCcVTlp>D5U}hjghEImtt_O1YJc+-(hJ<;Nh}M(cxT#&Qb~5 zof6bII52CBl-~QXh;Z2D#{lo0;~x-~+`B%z*^-M=OP1-`cYPcMd=2TQVD$2ctkQ7hN*` z%1)hAcz+=g5GhgtlSX~7NTZz0v4mn}K8N}|4t2R4R^)J~&E{a$D`1NWo61xxCNrMC zbn@#^DJIiYp~AD1XNgoyrIX#^Ok`1FW>IWnNtReFHIPjh@$A3n{{gTu5zUmfks$y8 N002ovPDHLkV1f;@SNs3~ literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/Journal-64.png b/files/opencs/raster/ikony/Journal-64.png new file mode 100644 index 0000000000000000000000000000000000000000..9bd90bdf0087db2d8d995c0ddcb9cb14e99bddac GIT binary patch literal 3891 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/LetterA-16.png b/files/opencs/raster/ikony/LetterA-16.png new file mode 100644 index 0000000000000000000000000000000000000000..dd060d2df71f1580a4e74a45dec66b29c96382e9 GIT binary patch literal 631 zcmV--0*L*IP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv0005zNkl(mq9$0l)xLkk7XK0d&PKkOp}_{X0^JLjTJpm|_h~3>N^SZi9TB=}-9(Lp`to z0R|m1)7<|{&-MH-=c9)am>34gM;gCX@YlZsb1oE{~No))JFYloX7l+BC7@**# zS0|rf3JSb)3J%%}6dbe`$lGfzP|#8NED4NG=}O!G^0rzifr)AW&}P|Y$2W4R<`3jj z%pS-knLUtAFnu5!XZk>@%lW_fLa+aFPTB{N0~2ll$j@?V=0D_p^fzD&Z8;C!N21Go z{>y|Kq68+~00n35Q}R*9KS8m8%>Y?H{Ym0LSBSMb{+IF6n}iYu;DAar{R9m0^SDwR zNR4!i$q(UK9{*+Sv|hvV2Lp&9@2h`8dX?{gc?ax?1!O2los5U>TVY_7ij~^@m$lJ6 z2oeKH{Fe_jcmWD9c{d%9$w2j}SzOjhI|3vw>#FlYI>6w8l)wH1Su0JjS^)2!PjCA} RWT5~6002ovPDHLkV1i}&4XpqG literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/LetterA-22.png b/files/opencs/raster/ikony/LetterA-22.png new file mode 100644 index 0000000000000000000000000000000000000000..02f35f21cc4ce51977d9161a7fe4f6c4cd27d976 GIT binary patch literal 859 zcmV-h1El3<6!Gi@s4=T2W6hRh&Qu@R0&N#b3Bic&&`I5~{X1{s!zBg}X z5Tz8-3E_IfJ+<}qkKa!xpGzmHOc2aq#CIX4+=4VCEnwQ1@1a)fzVNR`^bRN zhTKJkET9c}05ZLKB*4P8IybpeV26+dRG~m?%telly6VF-mPij+c|eZ?abUnovsI5) zr2azz3!U}Va5B3LUi}nNFgigQYtUn$4r8UZp$BHXCiRk<93Cyj-vWg`ZtRyPhtgy- z5trF>AYhddEj2cxQ8A9ZtKGh5-T~I1QRN`V4FD0j>p;NtOs)Bz%vPX%iDd8U1Mc1Ox+X_s9#aRp_XRAp*SblQ&CU%k z%=w;A4D5_E=BsEfI)>PSn)NI?7n979K4WGvHVJ4}#*=^k9m99aX9qu6_hgJhaxZaa^GMtj zlY**WR1xu)bxjVr!elAEc&g{Wj8%(~OSV~xkPg3GtW3BeNtCp?mgAkpc`CT!QD7!8 zGIb&)V^VAOkg6OLTKL0asV=6NGRmsbtS6Uem6x{yRLF{3P~URBhyKbY)P}z z4Lo;4w(A=?c3{0sm9002ovPDHLkV1kr>f$#tT literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/LetterA-32.png b/files/opencs/raster/ikony/LetterA-32.png new file mode 100644 index 0000000000000000000000000000000000000000..522bd42547f4c2c26917607a3df29d526e463173 GIT binary patch literal 1414 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 AQ~&?~ literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/Mask-22.png b/files/opencs/raster/ikony/Mask-22.png new file mode 100644 index 0000000000000000000000000000000000000000..e7b2310bad24afbbc1f47bd2e1bea4a9714af9af GIT binary patch literal 1200 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 A9{>OV literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/Mask-64.png b/files/opencs/raster/ikony/Mask-64.png new file mode 100644 index 0000000000000000000000000000000000000000..13dfe5f8f7c5501f2014b20be937df9c7fc34573 GIT binary patch literal 4461 zcmV-z5t8nSP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000o&Nkl>~C6;^y z3znGoo_&0VX9lJs;2-C)4Kwq5*V=2pYwaxoK;Fhe=@u!^WTODZ7M)YlqiLLuCJaU#QkITIJhMh9}W5m zi@M)Ns&FYH9AtH=-XVEyDMXtH5HGcyLcz;t3UU2ABh>zyin{BCtN_Uv=d>H2_}{~( z3hE6cM48%4=f3F@>r|*K1u@Qrd!k;-O6C^S^>%?8)15(NlihHS@q<6 zld8#iCRIZ-%qzGj-Mr#``lP*na#PJK3bM`4hJ*h!;x5+5|B1yO*V(K%g~9xd zh%qciT&L`pk+uoX`Z>h^73UOD73V1Bo>)f-_ry4cb5E2_Qhk(7V!gyB>Y1!#^2<=8 z9K;AFp&v5?K{n#&Y6X~DU{dvObt3+~w-B%XT!4S7hvMZQX?R(cisv_@P=Cc4^_QIR z^r9o4TV-AY4L z?&MdsVJsmHqr{QJIYP_gfj~92>;Q5`^cz$~&o>ebH zef1L5-zvkCsu>)7-IW~Fo(;i+6Wvi$$>8qy1h)?oCHUX>5Nuz>U@-GJ7kNeaG2}Q3 z$x)0ZM^HcxV{E&hFxC1LX4{{|eAkPZ>wE!=y{@9n{WACG51lSxj>9?3>~aRvJO6@d z)+aH^{1}Q1D;wZHFxZ8h|Jj6y&M}$=cvYRr!9Tx5@a$KD`U?b4&l5a3OYry%!J}UY z>P`{-eUhN|1i@d&+2oAb4K^FOx6(Cx@08>VqRB@4K)4sLgfBS|Npo~E_v%Vqi8%MsS;WJ4&q}l|Kuld%D zJcYlxi(u;lD!@8!&9?>o0P+bdK$Q9npw*rhycfSEw_4iE;cx6D_q#P`s@8#wA!nJzq*xR%ZF5e)!bIs z7VxQLsTKi7m{d{t`fG75w$-VFzw#Bq=28X&m{n~CpF)-(Oj8CF4`&5n;h$cOY4$$9 zsiY&uBsyc=I0tBgzr2Ou%Q*}(n3XNM&(p0=am~}Tr;(@d$z%~LK!o}wQ2c>O6@`Ct zC0cKjb7?ydGUs4q3d%9k;2;JFR-tdVSX3-;4_ff(nx|<`BTwNkeaQ+in?XABv69J2 z6qF*Dw^b*T)1N;NN&LADCPy25e^Lfh16-{1_hV;T0O2(YzlK z*)1BUH}aamU))5nX%-b=xst<6VHU&7Iutp)%^DpZh3{$OfjDLw=kRoaPa^YK0VJ9Q zpzx0_$@H?fW0IVkbairXKZL&pA4t5FB2VFe{es|&nN)yfO7=F}U>!0;oZ#=^i6my8 zN_!h4D2B|%8_^!Fdch}=xvT);>IKNlGOMQWkFO2V%iD)_i%^Pu}*5|#~{=$6yxF?aCjks%sy1- z$W!=4Qi{M%!OzrogA<0DRMD39@wH((H#Q%SvS-)*YLzXm+}_fDerlqJ68!lMtN_y) zq%upIG&bSZNvK%N!-^C!_;TMD0Zk(d)kF-X?5-DGW!H`@P)i1NHQx%vRfoFdIzGvs|?ZRdC24K=l1!; z_oQ6f)5uf!bL$B{FJVB}eB-VzmA?e}5iT73(PixO5y6oqqyheiGJ@pZE=V$%-{9~X zS9?|P{m3kY*#`WjHUrXPM92O**@f%pb!};Br5_+z37Kmj9QvreQnf#@s6G1i@jq7!H>4RKo9>%|ozNwBGRXWCjAedRD6yAScAGKQ@UGw7-9nrI+AJ!EcbCIX;XVws`pUNPaDN|YPllf)H z4s>f0`N{=wq>6{fh^@Dl!Tg!kyVQLO;<;9~a*27g}~h?*mvn#}N868_X`f;GidfVo=7 zSh|`V#cEFro;>YoFj;c1VeUypUeu-wPAWo2be7lPxpB$ zKq6DBafa7Y@X@3g-bPVqe7?}+WGHWd+5P)J_r|>wKHTWKwcvkV$qF!$K>{;J?EteS z;iJd|_*w_PY<#%VM1X=U)60Jz>xuiPLR%G{nw(F^Gn~UyHN9W;PjJw+4J984Ld|?n)j&uQes z;?^O%R)eSB{u5RJefxQBTb(L+85s?4QNSxzr^_k@$cnSLNa61u^-?*>dDF8@-Y+@}kQgCKSvEn4KTihZ+KzS&Gdxw1-@n*^>*}`7 z;dAy@S9t2}7mpCIJ^c{Q-p27u^lohA4o?%jl;oqgFb<*Jom5`EQF}#ZShCsu-w)cM z>VQp?NsheWQTRb|W?WadAYX{DXYo~5dsY2BZEO|~7of186-v`Pp|EdP#JYJv(k&2T zVJ;GQbD9h@^i6vTFClsGvGQ$VfaKYrR)DxL%gU?U+u`<4O(!|>mNqZN1V66eVebM1 zy&_NHE9Ma#noIEghXe=b5FD6Iuzx1Oz8M5_2UtMr;)+1Ccy5f_KOEx~9E6@`~^~#Y`W8DM7SN+z4Kz10NYhe?EA z7iX1wzs?yzUq}^9jA%1X3qwNO;55!h0Kw{|&b9q0^mXtxG_jF44i3m0z=mnOAnU zZ|LXM9a3?v3b33hD-L&M+@a^o61cTX1=ksss?P=tFEdAls(S_URJ&eM* zf=A(lcv*0_ael1NonoCcfWB#Anz2nxkf^qD`Tyd?DxS(i3&m=`tAxkd+aR+<#2HM- zo5Cxud4DDap}ZXQGzn^eckAHxPiBy@O{)n&-#ERkhV`}z7#L-C zU-867*L{BdXalyYcR*&KEn>WF5&X_Ty&N80^S*+9Z0d_aw>k>%W##pjO)-`L!@ReFxZSd6L%^%2c$5o97nA%JZ-RfLz zdOX#|=xF=?dhG(5-b~iVva%#o$o2EOz*BEOFN;A4GgxPDPq#WRVWeLBe47bCKPVoj&2fJoqG6n+@Apyl`W9aTsy;;QX}M{z)VP-R^Ky9F)s?0( z2xKypx;koaJw<(9_37%Qbd{wgVBeYm^n;^(EnGu-S)Iv`Hso5`&3Oc~QyBy>Xj0g5nEZ&8ZWOLV;`R)|^2uLbZC#=_gitxnVQwzULl za{(H53lGaFo=%-=T{=6y2(Wi-lm92IO2q#M{L)3+m6ayu00000NkvXXu0mjfT%xs) literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/MusicNote-16.png b/files/opencs/raster/ikony/MusicNote-16.png new file mode 100644 index 0000000000000000000000000000000000000000..f43c6eeefe4e9fa593f3402c93c5908fb99dafbd GIT binary patch literal 507 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p>QK$!8;-MT+OL8%hgh?3y^w370~qEv=}#LT=BJwMkFg)(D3 zQ$0figD*u3fyQQex;Tbd_$UAP|KFZjFK5lO%X9PU-t1rM_JrM)m6b8)RY4Y;rdiI6zBB~l1kmv1cw8-ZoOpEde}`WaH?DebYTbK=olR?Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv0006ANklp?s2C|_8Q5Y14hvE)93@`4aA~*yudh_I|C%q^h zyp_$%*F0f`GS{td$>BYOB%ger=XvuE0T}9cUG~?$SEFx{P%AB-<1U@|Uf(Do)7EpW zrP`>+J|n3vyz>m6GN0o9$RDgEexYdXv?EfX(FALRt7o zfRk|SWCc#QgemcLeI0kB-(brX7xrv;*R+SIhrc2&m%W9@{SUAh`hu7=?=5`Qzk*ue z6Qa_bx9}Bp8Mn<3h=|3(VcL^1d49{;TDw6p*P!cBWeFAI4Z`BgU~pKP+8a|gx-*LVDb}eFr892jlKVR+DS@iM%aMPr<+W_H1#+x zm5;jz)s1F_ZG`yJkUxd>AGfyZ>m^iS->QPpH zhEDmEv|qF*d~()uI-hFz`S`BJB^&*e-(AT+-#+i!MJye000000NkvXXu0mjfXQ46R literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/MusicNote-64.png b/files/opencs/raster/ikony/MusicNote-64.png new file mode 100644 index 0000000000000000000000000000000000000000..0f8115b9cfdc6ce479661856e80106781694368b GIT binary patch literal 2340 zcmV+<3ETFGP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000P+NklvT+24hrMY%~n4e&V`F_6N_j%vvxi1d^z(Znq8K|5)jh0uS zC-r*>I&VOsZr_YWS<=7U-%S+aZOZbVfNc<7JPL5(G{9@m{Q$?i?m@F{7%X)0vO*9A z05e_4?D2fhif6jNgWc|Fc-%h?hx}hdiT=0XR8`FF9!rsB)~+w8Fc>K z$!~eiqxj9v&!OFM8!|QRGe#=kB{T%l0KnM4{LDAu*hh+g*zqZ}Sg(Rz=^c|wBtH`p zf=B=qFu3MlJaLa*^Y@Dn+HXOd{U+3#UIm>Z{f>|jL<0Z|-Wg_QPVt*;pFpd16zYuU z!9eAYWox$nT!vd?cd;m@6i(saT?^@|qF>j9| z0g%sN?4LdMHCyoJ6TiU{g7xMr&}<%oLhV7&D>6s5@?_6a(;ylESndDvE>*!hTG|n29PpV^S1)qk$n30C@~LfAYu_FZN`e-_6o=-VK=FhDhf*@oSC4 z;5WVnYYcYm$Eh6!EYLbxx_al{T1qy2B1!V0cv%xLyhiLs7^c&9?c=p%2JuR zQXvumxeOM(KRxlUuy`zZ>FP~4xG%1ir+Ca%$&iDtnkv>FhO)%tVdqi&s>BmelyC$x zRa=2LKVepsgp%Yr14g+!IN!D@8UW}#bLgM!R>xKQbaiVOK%|2vs>o}ntGadabmqrb z8e>uv^%@m!FA*zw;A((@%4IP2PaXI&EFRZ;Q0XYmhf9$b;u=_k$ z@Y2*R@c|%7k;7o@pWOEauiCFrZHN~D*$g^=c+cnILk?E^RMq-Fl06yiHNAjTZnJ40d&oZW&{{If!@HA{l7l7^^dIogHJLc%Swq0-!ct0IXnehPT=O zVOV^n_60K9iX#B%{KJhOu+F3S)d^<^fSLy{0XTppPi%V0DEg99SwD^~Ep~Nyu6NKi z<5sFXWK?+0*eGuSH?B&Qr!pA(w)(4K@f8WrgH2KW-~h1GUY&(59dasbrhNL-(3W!r zwpLt&j`FLpx$J#tFTD)Gk`dUDI}CN!e#lkt0=+!@woy^oivZC1jWr?Gc@$r+d5!?6 zdN2T(C{G`8c`{)C8}!tU!eiS$Wg8nj+wbsShfd#BR(!B*1hx>79gWu@Sa}&5lLsJQ zy%*Fn%M`|bL)H6X@vAhaz^d?xAAprE8!FTN9=a+%f&*Qju`TV+bsxi~yb)ewbN@q& z2HP93&ixiN7Y~EiaGG_#x$+9@Jc=(Zhc%_|vd*LU64eQ?$XAOK04a9f{DfW8zo`2-EdKrnl?yo^DV~e{D($JT z_+sTB34jW50w9l}C)#tbvEp}=(Y+AjBb`U_Matt~mY0hUfRS?dl4eoCAG>`GrKm=j{FJ?`_7&*zsC``MgF@rCp;Fv-fql>j{Dxm1BkEO@;g zx1h;7JnvQ)+1Sjs=I0adp?*gIl!^-gxrX8`PCNp8f;XY7_QPcr@1_om4*x zmObIMx!>arFz>&a!R_-)aUR7NDEh!CD-l-$^kjI+O>fs{4D$wlPI6*(K2y3Ew33V|A+N;?c2Sbt$J4p!=9xg=5Y#(f=gsgI zI@>QM_9#A0`Ur`C%Cg5Fp+ubkd=uWlEKhtI0xK`_W_Ut4pCNq|bdtPDjU-hUYrGfp z{v`pxXp({EM3wm*JIN8sc@%Gx_(3hP_bukj3-LQk0)T&*TtIf&sOp(Y%UP%(Q{aUf zoB66e#va8dOWH{Elm92t=in_F0J|e7>Q`Mo5!)LgXPQP1XYr={nF$3MRFZ^bjd_ zJwl3E%4Z1*Ao2^~y?wnjuUjp(GAevYtc*tD>?8a8Pv-V)fc^u1MIuTaW2Dvq0000< KMNUMnLSTY6KLZ*U+=)p!fv7f#TG` zAxLl%!EgG`&*5<32cu%worY0{L9A7~=}6b}76Isk~1IN~P)K3@?4 z&zpALY4A7Z!>t0&I7qECf*j`WHIYAjW_h^ivJu4lvb8y9VL`DD`rG0ZKvcZ$L@8 zo)6*!Fng}&gE0q~LGCMnsiR8`P)pL0I_sTkS+y)n+TA3GC?X<}@U5p+5=B%JBvB7i36a8NN@4Ax2Wyo=l$u>(wiaH>t=;eY z&gsE1ZB6Su9r*bF&N=_@??8z?#YOMMMu>!LKL4jB<_AEiHz);9}$A+Ax0P=^| zU+r#zA^~C>iUkzeQ2CxnK(WAhdVEVs05c({EM!$`abjMeSb$i7SVF@(FcV4xK=_i4 zBGCB$tYH}6ir-DsEPp%TjWAXK01RS@aBJ(sP$)EA{2GtPgKwS=MwkiON+%F2tX9Ml zjFkW&5X*l6)RG6?SGo@m+@Cmy%*L%h<;>L7dKk(r zKrA*ds3cPS>JLF8k*FMw#hL-=L(!;N*kJJ9r_-DC=M>HC(pEb>zD#Ms*YHE7!@puX@9@rngmHDvan3KH)@mGwbdLCTdjsGdjvb4^Q t3!Qbr#)-P%zK?B(j`YUk@c;n)9sqKTm5v4c+!X)-002ovPDHLkV1oQb&B_1( literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/MusicNote2-22.png b/files/opencs/raster/ikony/MusicNote2-22.png new file mode 100644 index 0000000000000000000000000000000000000000..577e5623063d578900639ad1b3e1d3a3c3007558 GIT binary patch literal 1201 zcmV;i1Wx;jP)KLZ*U+=)p!fv7f#TG` zAxLl%!EgG`&*5<32cu%worY0{L9A7~=}6b}76Isk~1IN~P)K3@?4 z&zpALY4A7Z!>t0&I7qECf*j`WHIYAjW_h^ivJu4lvb8y9VL`DD`rG0ZKvcZ$L@8 zo)6*!Fng}&gE0q~LGCMnsiR8`P)pL0I_sTkS+y)n+TA3GhubkVPfF1P0YZKKLL(5mEM15790x$a+}(D!4qVRtIOliI{oUWa0Nh1ygVQZb~`5q0s|2Tfg7F}I1F#jani|I zF5k0d1D;b0wpKU~+Bxaqlz`!NaAKBzB4w-#6Q8EGh}nRN$eNG=G}BlI5l2>FfKmWh zhKg!H=^*6EaXJOLt zB9H0SCF0K{6`3nm6lIC3sucj{yb~v4mO{bhV5DJ=T~-U6akiW`fxux?-Yu^8NcODH)LOBkC`FC+oiA6!8~rZ3 zyu%m zX(p%g7+Orw)Ht%7P+Ybq@_ONym{^by=MmKGDt`t5s;X8N3ND8cV>GrPFY!keVqLTU z`qy8t{z5|n;n?6z>)}I}l1xMyY2c)TC7U(gm}6jw$Hb=Qrl+3Ta9}$2kef-IbZBe_ zlk)>#&h+l9^Z9%;0O0j{!*gs>%|RP#cKDtP=B12`j8r|m|D;WsidKtu($-fMKRbEq z#I3TjvWQh`7tUX7e=(RCa0siDoSJkPo6I5<9T*Du1^lB$A`zjp{doWMXz_`qSeFDg zD*cYp=(%ex2O1h09^rp&czC#W_s*sVes`_xb8nmIXghW@6bh|1*MAQHRjcjq0Vw2G P00000NkvXXu0mjfKLZ*U+=)p!fv7f#TG` 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/SpeechBubble-16.png b/files/opencs/raster/ikony/SpeechBubble-16.png new file mode 100644 index 0000000000000000000000000000000000000000..131c5ddc275a7090f2ba6e28acaef9ad17beb63e GIT binary patch literal 657 zcmV;C0&e|@P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv00062NkltI>-8%Ju(V}Vpot^AYadC0!!VCc$psArgd-v}3|6jej zg;n$I+o%8Eym|8fwQI-zU%GVYe|~<(SD6H6ga?O&IZ|h_3BZ0fFU~@WHU%}UtjZoU`)6%027aRa&qiTQZz4L zKI^}_n(BOTG=d0iZOvJrct*DQ!i59>vDw_&QTJb2NpU(b@v*@TP*jlbfoZ;Y@zDP{ zb0+-XxN*t<0|z$#-??+u|Ah;u{I4j_|7&4xx(n!RM~tKlOiXEe_pS%~xvj0{4<8?2 z5Kt@%i1UFs3&{5ZCK_R6jVMVO7!Jaj8A00000NkvXXu0mjf)($Pm literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/SpeechBubble-22.png b/files/opencs/raster/ikony/SpeechBubble-22.png new file mode 100644 index 0000000000000000000000000000000000000000..7b8b5a770ed8be3b05258d1030a9f531b7760e1c GIT binary patch literal 885 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 N002ovPDHLkV1iuLpnm`W literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/SpeechBubbleHand-16.png b/files/opencs/raster/ikony/SpeechBubbleHand-16.png new file mode 100644 index 0000000000000000000000000000000000000000..aa7a96863b3add616b0adc070387a606642966d5 GIT binary patch literal 845 zcmV-T1G4;yP)N2bPDNB8 zb~7$DE-^4L^m3s900PNLL_t(IPo0u&NK;`H$8Tc$AYx0+urFniFNq(bqCNy#VW6Of zL#O3Lr!95b)TT}|1(%ka^NsmBDHB7J%vNf1vV2)i9Zu)W+0+Cv#DuUfezN-a+`)z- zMReit+B=;` zzHY{xNel741k~Q=qF2s`OvpxlQW#ofA{Y!BD@>mn%_|)9^em;Ml9KN>cx`PCCgTX| zijtsi62Q=&g~ozdDDtDxD9MFhueQSUIWeI^Xh^V*lFOw#bY&V|U7aNZdxH5Kn44a{{v-pcPcx7c8s@~^N$xRV5}knlH7zna7RZoe7sLTwR^$e->;d5 z7Z%2?0;+eNsD6-)Dq%Frvt!VvklHJkKQ6+llU@zPdp$_jtDxVS`;+)WY!5^3Z+l$geC zA81REIk=^!aJP)cVR|*wf4um&ABUMtmP{u86%igX`CkGwN2bPDNB8 zb~7$DE-^4L^m3s900b&YL_t(YOO2IlOw(5whdW>_WQ>%QMIf75vP_4{E-Y&#)65A4 z#BwQ=0Hxeosii<^osA60j278M$Hl=Q5=0^{8v{4R4G@%D3l=Chxu+4vBwW1kWgoW8 z@Z0~K<=?=-(0**rdHTG+_q=a8oGm_%j*gygZf=U8K>r_fCo?7s3eK#Sm0no8RPyyd zdVTg|rBY`0_2pl7adC;Tx3_y+(@8j+>a7>BH32eN0aFqNSxCeuqCDV#IcCfHTm53k7HYe)7aZ zq07tDP$`lqv?4DZs(2Ar3`J1Ig<_;W7doxV3LPIe;=zM%^!2qOG9u&;5+j8>I5_as z8ONWkhb}HoLYtb5>qVdA+Qm$2y3|pCREZGtO{Z~En@UYt=*UPXhKD=Q)6)ds{U3KR zvAo3D`Q{s0v$MliQvzLB7>7DVLZLP18DqwDp*0Vwu}3l6m<^xzyb&c7psno&Sm@y3 zJq!%Ap}P88aJk$lj!Y&su;sJRM~}uJmqbwL)%;YesWRpWEH`uz2@aw>D;l-671Wf4 z_V>5KWNHDQ|Iuv@c}gVH_0akGQKZXbDD;Y6VKqG-9fXQ(3AEB+lWk+)i9do0un9jcH*8ZOvmN}%oSzrgF=T{Rq6SFZTZod#;kPE`F*)u=q3 zY%PD{dK%({ho~um4wObCDJGmYiY>ppyAfSow{Yr|`Y$IZr+xG-fAGHd&n8nV9aAz< zX7fG7hY4t=1WGbZiSV;R^~VBmHdng|T3UJ@ZaiLwb^4eG?WEPH{v^=pX%l_?@^~@6 z*GnmMy=i~32;!suo1le-dU$$zoZGZ7PH0uDER;;t*q8wcQU5iHEuTQ|UkrgVQB1o} z%5S_?i{vE9GgmHGvgHy|D3a#cF(uH^(Jmy$ig33umS)OAFRKMOp-Mz$Wf2k*Vpcpo zJkF7|@WRy@6zJE%ni6PTT@`k}{Z^%q_nwJEzCMdV2l=a?@O>8fA9~Muc(~`k#w;!- z!k4$*#mr9q(rEmRnvyY%5D6!?y=2P)X5GEc#PO7!{e64AuGn(VrZdb|5;5IfGn?;X z_pW!ov+0tphnPr|B_;W52M+9Sw)Kw9=Xg9`0y8u#%pc|U&3OU!U$#Djw~Z_s@&Et; M07*qoM6N<$f^Qcvv;Y7A literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/SpeechBubbleHand-64.png b/files/opencs/raster/ikony/SpeechBubbleHand-64.png new file mode 100644 index 0000000000000000000000000000000000000000..62e4757973bd3093e92dcb29b3b0f344f4e4aa93 GIT binary patch literal 4800 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 a!2bbJ-W=X7b**9m0000N2bPDNB8 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/SpeechBubbleLetterA-16.png b/files/opencs/raster/ikony/SpeechBubbleLetterA-16.png new file mode 100644 index 0000000000000000000000000000000000000000..d6b486bc6576c9934d419506779babf58ff8c9a0 GIT binary patch literal 839 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 LNkvXXu0mjfeXx^x literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/SpeechBubbleMask-22.png b/files/opencs/raster/ikony/SpeechBubbleMask-22.png new file mode 100644 index 0000000000000000000000000000000000000000..d0bd2b9cf13769227426e41a9b8394e74d21681a GIT binary patch literal 1288 zcmV+j1^4=iP)N2bPDNB8 zb~7$DE-^4L^m3s900e|dL_t(YOO2I#OjBnV#t*k@H^4&cXbHm^h6>_FB4e;H$S4k6 zV8}&KSQr#xjJw1QBhigjK#HJD21Y;>Fcd0Qfe8p$?obLHSGk19O~XYd$+ADT%<$}- zla$bjqfO2~C*S)!&-cF1`;;KI_%Rp^Qx1m{>EZ4s{_afNxJZ<`_Df#Y`p>zS{t*h# zy@-ku3^+R4-!L>Z^wrVPd3!5{+B*_xa?sl9_SLHyucoI5u(ULR#l>+ve?EqVg%Qln z4Pkb65Ko^fF+JT6nd|`)5~9|)T$2=SZS5Ufen4MepC20=`C@i<2rDa7SYDp|U+C0S zA0{SxF+Sdd#>TtgySn^F3Nu%OlhDtzL_ht#x;jlmXJ(X;_f$ivkV4U0jke|joKN}` zVJ@+d-V~#$<{ldFOHeDRfTFJ%BO@K?>uZ9auh#Wg-vHjfDbvm64$>xeKDA>2#|AM8YQx}QE4sVu;pp&DJJ}X3 z!u(ycvokY;YS&jPs?b`&!5>NjtK9?^WdvFZ892qLL?Y3O7@{5#gaiS`DUjZ|LqnCy z$LQ~GMoGyvuvo0)gh23B=YMa#OcWGkud6IYLFea((c3A;gM1$58VJY=nCK{A zp!^3W0(WF1_^nI?GA<#2$c7gu0+O;~HE37YuSkfGd_`OorYuoDRY57Ac6Ul4&b7u9 zi58l!>7l<^3zex1cpD_+g!UB@dKunYKf?F@P~593p|4LVrJ$XibqEeVK1cZZec7-X zN|}Fjqz$Ecfh3fHldcxXjxs^^w=9IZ9KcCSPk8Bl4-ef0#QDeLadWjAR3^I*s{{LP z6GlcX|3{Ci)i#PUe?@6J%7q+cgmZCZ&rx_UC*|};rKQFoFTnt!5FY&O_rsNW3Le@? zuzkk~NzqXoN>$Ljyi9P|?6{5XBMr?wof!S+X6V>h7il9IsVWpAvK2YuJMr1hFz|N= zATcbOR=8PdPL2?!ro6P*@*?SU^qNX31sxsj#PD!C0jD-t5Y-wy7!?#NBQ2w97C z16o^CjoLxZL@8lPjc*&*c8tdM_{+Yjdr)PDi<#%c&;4w%dU0000N2bPDNB8 zb~7$DE-^4L^m3s901?SaL_t(|Uget!T#ae_$DiqKnn$mtu~cS8mMoLCcPwK|NLsX5 zGWloUm&g((WNW09b&y2E5QY#l8CxYwvP@}{kXEEpQKAw3-ut@EbN;6~sZ-7S=l}YA zZl_N@=Q+>!x~}_L?;{9*!#_1OwdVg+S2t@9TEHbLY;;IN;}lJ9n-jE9*XTa#E0&myYMp zA0t2i30}O&LSbPxTTlOb%|<~%7W-QUyXFycbJLKWorEV(?&0CX+ek`^L~u|5)_b~? z*o?5g)wHShYISw>_OKfd$VN?@-E{CD&>x`wWm-a`UOO^rcx^d)$0_k^{Tc|?N- z4J>MiP`$S^bF8D;q{-Z6%NAy*rNy#`e8{w!gFpW);Oo_^=UfP+O%h5*20_O2_2|)U zrr9{Y($iy+mKMWTYHBoJDJfA%PQJw#X`dGTOxBQ@c^^-oCbRq9Wxv0L!-s!@fkE%! zx^?RsR*yu~NA&91<1E`69h5|>`sJc1wlOs9doeipBs23grsZcS zE`G^g^SPOlrZY3&fma1y(*FB2uLz!iY2CehoxhT0q^HN>_U$mZu31*BqtnctDN3w5 zSrx8q+_>@dH9ssXBuFy#;^J3K>o2)e%gVaP*MAy5A>kTxwBdZw&nYR&sbhzI9-4IJ~?(OPV%q z>a4U77GJjTm=dwGYa3_J-SI{G4CQBk4Tx6cdO+FDMP3W36$ zewWV2?%uu0lNbs9>C*@0;3cOgg*t~B#&BNPA8xCLVa=-X@b#XHQvoY*>i7z5S~m?p zI1h!>oNjQMp^cb;y2y0M zm%+c`ny(5xB{=I>>fue2Hi{FqQ4}vA@}wFr_=yPFCnEloD)RnlguKX3$d9+hi=?G& zIV0HL4okWO;z#{d{9>02uRbYo`7#=d)x$AG^$6_5tr#V4#%Q%2m@WihrfLAD{lgzt ztw$&Y9~l_}TC-6@>11Uw27Wbny> z0*-GGF<#tL4&Gk)9W#aBxYew;1cc`Fw`}Qs0_tgn??#uL0^uQK>rY)}${DYGMj(Ug~C+;q#`O4tO z2;MMnWmyWIJUuOPcJd}qW-n=;z;E0*$Jgo8zo2<@oi$tltl3}?9)6C;dD{CqImy*Z za@>~a;nn>SC`xfEr}=Z+KgXEvCK#n}f!{ZM4uZdTT!8;N5o5%i-0VlHd!Q`5mHP5h znkRTWVH*bPSj)^_S@`SM&w`eN!?Z$X1)|WlZR9xCcfqm|?Qm_ofUqA0 zEVga~bM-~#;BAC;7}#>4QhUBEyd(f?Yja;=(?-|ScjawijY`@d7I#5jlmYS+CYAE` zy}s7RsSTgY%sybP2EJ|A88Q0>_^lFQD{hpT{Qw;k_&e9b;U)FZPsd0h{BXe)rtJn- z+2K_LPZluSe#&`a_wFC_Dee~*=GLg0v1oQb9_I@Z7nKTiVS7|%@MQL+`Jk<;h}tV) z{|XT!MNe6%8>_MlMvX^faH9zrrLvhjJlgYQ_M~}&A1b)Oviks;0Lar<GwVJueS$C9HsLKT{s=Y65@dN+8_UI+Fl=xB#9#dt7M`?|p5o^{!J8;;V+|_vRq& ze4|R?|JWs9?@|%NMOTHPPLbvb-dJrW?CtDi0#Fp^E7Lr|%LK4%*A~77sIT|F24-bF zyyHi`all<2IWaa!57sGX_VSu1_#55=esU5qOmtBg>dKlu!CMMT(NBFee71R1+w3Ly z%a?z{^5u@9!iM#0QmOEH{yd|?*0mydseLWAuBn;fIO!`qx!xBKFLmT`UXj^L@Z{}x zFA`xbu2LB4%9=gF4-polr?z3Oz>@%G&6<2(m_L8k)t4`yv6gnW!oGb~;Yk1srglZj zITC__4F05t8u#|J=jGuk)NOT8hf)1$7^b$mLWd`5p5V;{M;Ph#RhZsZ)$9qJ)}>3o z!phRrS75PlAMJn21v>dHr0VA?eE>Y^<64V#n8ozfvgIA!4jbd zd|Xu>coG2h@TUAv7bF~SfYgvSGP5^jW=n-lPu*@zo~*)@VE0USBti63Uv zM{-aLMEiZly}h4PeHdzvmBj^_|a{0VXnQ@hT=a$A*)V-ZEsV~lKR72vKCbHa~G*1~`Wl7FJaWcMb*#+HN zwTBVg^F}JuV4!9P({K99>iLSyp1>=DCvaM!p(kK(KRK7R0GpTU3iavJGblMZiU}d7 z!YOUpzP%!Nn$Fz38H5SL+u)MdXNdE!18L8%veiLP9kw0RoXe%RW%qnH4HIqvR zcj(c)8!lWp!39uLcwgVm+~4A7}rXB_eKt`+$6 z=Z~@}a(Bf|Q4#{%3iD0{{=&LK>1<{nE1SIaol-d=Ke8z+k} z5~nG2cmq@>bNHWqHq{C|nf~-?<1229lK^Ni!iJ&#H*W^BzF-=k!&hZoC9nCiIxWlV#&%e*x z%R4-R_ww?9mX_9%N=IYT1#CFlaOlt>3CYRPY(9`7JDE`(c=^_~$LeXY9n=hm=Bwbi zqkwf|MHq_Xc&H<9|1a$xm^W^0rQTjy_%FU_TJ_X+&MP+lep`N27ava}3n)3I78-YZczZVN9`enf@@K;R^Rk$(b>#8H?}M})2ebNR~r|yli&?jEMHWVnVHP9 z!S^LO(ukTJPRy=XuU`MMpU=)9sIdEKGKluG#+c{|nF!)yGZAJPpPHEcL5DCjtAlH{>^Afnu{ z6#2sm6DQa`R(Sa6LjqFvSy2N|wNC27toR0!X*@t9SP?vq_DVO{^@<5+fo)*s=B~ z*_76gwXK;C82r&_vnCJ9grGZW)bK}zyJP=;$cHgKIlV!FVl9%v14ts zZryt43ur#a8W9^lA{vjXw4cS*$&E4FVzon{f zuEX?qS_&G28lA_)qqyF)%S+VnD6TrU#o{~o7i>x~= P00000NkvXXu0mjfzLG|? literal 0 HcmV?d00001 diff --git a/files/opencs/raster/ikony/SpeechBubbleNote-16.png b/files/opencs/raster/ikony/SpeechBubbleNote-16.png new file mode 100644 index 0000000000000000000000000000000000000000..0953867493ade4f76de20a589bb2578181ee6dd3 GIT binary patch literal 810 zcmV+_1J(SAP)N2bPDNB8 zb~7$DE-^4L^m3s900O2-L_t(IPo0u|NK;W5#&2T#L&TPvVgHmL&FLCTQ!=pph!u`> z;YUIyl!j=oreUclN=c?p#mF)?p%g(9QpC#CR;D$tE1loADWVu+LKuX9Sv{R|U}Gjl zbm71~=icA@JnwT}jXWgoi!5tV;h>Qj)ikpP#*+axQ67EEegUot@Vmr0h5z&Ar}`jcz9S3y}k{5JUwr5n#!AB?R%y$?O7?ky9uVsk)k{X8;w2S`4><` z%MDyzoo2%t7|*{#a!?yoA!eMCRAFXjkSSYjAM?$&!3M)~#K*;$xT`r?7OQOv)1EVf zCrDrw4CeWlQ2I9@R;)vW?{%h3;emlpNTmUfIdTJ)X0wsmPB?ml1xCY)3Q(b|>j{IE zevc3%(&3~}tqrcJDFwNS6C4?y-DznlpXcU2KwGcH#h^i)KiCgVc{!eTwlZZ3D}3)k z?yX_UEiGF3iS|FV&4NVYucc|zo~NeXG25e~eJrrzqC%!j;lhFfRFoIP$J?u(44=SO zz-!;$Dl0rT){lmUT6A)Tn{Wo1R* zU0ht^$k|!4)MQ;Edj%O9w=JOcfaKtonUT6iZIi1R`Qwj&`><0ejIXXP{i%$N9{R5W o6!P%cl^T2~aE%1C{a=gx0N2bPDNB8 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 literal 0 HcmV?d00001 diff --git a/files/opencs/raster/sound.png b/files/opencs/raster/sound.png new file mode 100644 index 0000000000000000000000000000000000000000..b072acf767636af2f82471ca15a7713d9609a694 GIT binary patch literal 1144 zcmV-;1c&>HP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000B$Nkl3maOaDe9i> zKu7`*5FW=XCo(wIoknlTDq2nN!^Sl)77W0z9mNY{x3c2#;-ArN{Q)h;^Drs=H}s6x zo)1Kl1bo`#m_D9HyZH-5O&9T?<$D}5Uq;OI89d5l#>|H2ixk0Ujf_7cmWJ90Bnd#3 z<|xjN+(e_{O$dx@wOp0TL=Era0n^ur89zs>;S)rJ*Wu*4z|j0{$pI=gkK)YGIvVsd za4Wldh)XMb-%FzFIV)TLp@|9185!TKm_Yo0NuWYKj3)=z5YfL1m$I{GJI$9{BS{JN zs2|2;|0?QrFT%lh6du5<8pL?-b<_&ai2w%+4^XZez-aeRsL`H-oog>Vz;0zfjvl&- zkoGLfxcdta;87mNBL|kTPxBN?*|x$1xcLMgid{iabs9Eyf8haKd=FC5%Lu5ZP@-rl zJODZ2l1-Q3S3ZGaMYHq(r4z?3Lkp)!p zBp46GJy}EPfS7qDx3dzD1u{_k&e)s8`S8K=qgKa>rniN2CEDu@mP+ z{N!W5V*JQ;#Qh71>OVrW@E)49=h2{f3ysFN(YEJfw1?+W&W^w=uagGA%!X!TmJcu~ zx+dZsPVuhaBu<>ys%B85d>M_-i`cCgMv*)$4S?8mEB)0=+1T&oe4}_Z|2%@+Ie3^s zm}DVo0Nl#>&7s!iY|ZmI&xr@vr{Q8!Fv_Z>0mvP%q~SK!{7%k^xKD8!4*6ji=%6$J z;=Hf*)_j9Rc;TOh%O_sJOu;ToK%l)bNggB?MR>8@`Du34NVjh#?v*0-=#PE*NCKG@0{U>`qw< zX1WnPWnTF&&bRD=&29*YmiEMzv~`-NEz@e+IjW|dJC1zwzJCK>;KkS!2QVoB0000< KMNUMnLSTXe=@Tgc literal 0 HcmV?d00001 diff --git a/files/opencs/raster/soundgen.png b/files/opencs/raster/soundgen.png new file mode 100644 index 0000000000000000000000000000000000000000..70ae43a1d773de628ec18d67aa24e3c52016372c GIT binary patch literal 2041 zcmVKpijq|>J`*vfn2e@8HOrhnd z((0M!c=HpPOvZaZF|HeW;uFSFbtr^*TOfY$;13^s^4(%yd(SUF8fxZ_J^G~+?@1t&$;i2-`O{y# zxNKV=p66ql25+7`8B~JmmWO`y(D+)c z{-K90SZ^JDQNOj|}pMBve0QqhN^0WEty1Tl2)7{}{r2}XH6?iNg_me;Z82pa2QQ8#LibX_FR9bty5VNi3BS2cag~`sr4JatlbD8Lvhv+Yy(i5C6wp{ke|QnuALFb*?sLb{npWA zf2U9=5GuviEnC^#)5Gg0{)q|$Ow+`199+k_h=fZlRws~5wot8BX>MvF)an)hv>w%3 zUIP#cJ*|b_R4=%>ptV>JAl-;{@5guVj;^e%lAoGnUB^21et8eGb8~ccc5vqG8I%fe zA`x1XEhJM(3@M33A{YLCjYJ|5Ckz9$rhjN?$Wn%wl0sbyV4-J0Zv+UWSr9^}8n-~) zlN6hQicztOfVR#sL32$W`Y^aRCH39U8KlvtKU zDwSg0x(<3b_t2VbMK+qR-V0G&w_c7wD}=yV1cI6AX|xuYmdO=Y?!<8&Y&(M18X+ZG zDNMtlSgHi3lw+12Y1p7)R8;b9LcHVAkVK-W|k zLQmGuT{eL}4Z|2=EI}mVV44Q0R2$p2_K_VsL(Fw)Z|gt^alvH6Ow+(| z9BkXh_XDI9%q=VsDD@(MQu;~>M*xH%Ews$l<-uqdLQVt7=lAa)Ef&j1b7ynm`mQdd zG?<;6C7n()K9Q&9)riLv#9|4w)(r!#HDRdmJdYp}bX3o9Y+|v3H-}iapr9bfLTW=(}i#_uI^Zr7g*5d5wPX>!*GE(H}D6O~`2n0Yd zF*Y$bF*cC_T);65Bi27Kuw&-jY} Date: Mon, 20 May 2013 20:40:53 -0500 Subject: [PATCH 043/213] Added #include for QListWidgetItem to usersettingsdialog.hpp --- apps/opencs/settings/usersettingsdialog.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/settings/usersettingsdialog.hpp b/apps/opencs/settings/usersettingsdialog.hpp index 3b968e549..c69906ebc 100644 --- a/apps/opencs/settings/usersettingsdialog.hpp +++ b/apps/opencs/settings/usersettingsdialog.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include "usersettings.hpp" From 32e90bb73321602f3c00347d53a822beec248637 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 23 May 2013 17:27:44 +0200 Subject: [PATCH 044/213] Fix chargen statssheet --- apps/openmw/mwgui/formatting.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index aebaf16a2..fbb2b74b2 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -251,10 +251,8 @@ namespace MWGui MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0)); } - boost::algorithm::replace_all(text, "\n", "\n"); - boost::algorithm::replace_all(text, "\r", "\r"); - boost::algorithm::replace_all(text, "
", "\n\n"); - boost::algorithm::replace_all(text, "

", "\n\n"); // tweaking by adding another newline to see if that spaces out better + boost::algorithm::replace_all(text, "
", "\n"); + boost::algorithm::replace_all(text, "

", "\n\n"); boost::algorithm::trim_left(text); // remove trailing " From 3ae02547d2c774f0bd7c4beccbe0ea0473d1c3ba Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 23 May 2013 22:42:36 +0200 Subject: [PATCH 045/213] increased version number --- CMakeLists.txt | 2 +- readme.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b989297b3..7ee938206 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ include (OpenMWMacros) # Version set (OPENMW_VERSION_MAJOR 0) -set (OPENMW_VERSION_MINOR 23) +set (OPENMW_VERSION_MINOR 24) set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") diff --git a/readme.txt b/readme.txt index f8361780c..230150d6e 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind OpenMW is an attempt at recreating the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. -Version: 0.23.0 +Version: 0.24.0 License: GPL (see GPL3.txt for more information) Website: http://www.openmw.org From 1cfe037d6b6e2ed4d3c26f4934a1cc38d6268e5c Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Fri, 24 May 2013 04:49:20 -0700 Subject: [PATCH 046/213] AIWander - Added support for the Repeat parameter to mimic vanilla. --- apps/openmw/mwmechanics/aiwander.cpp | 4 ++-- apps/openmw/mwmechanics/aiwander.hpp | 28 +++++++++++++-------------- apps/openmw/mwscript/aiextensions.cpp | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 3cd78a933..a73047548 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -1,8 +1,8 @@ #include "aiwander.hpp" #include -MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector& idle): - mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle) +MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat): + mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat) { } diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index a71858feb..e06e714bc 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -6,24 +6,24 @@ namespace MWMechanics { - class AiWander : public AiPackage { - public: + public: - AiWander(int distance, int duration, int timeOfDay, const std::vector& idle); - virtual AiPackage *clone() const; - virtual bool execute (const MWWorld::Ptr& actor); - ///< \return Package completed? - virtual int getTypeId() const; - ///< 0: Wander + AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat); + virtual AiPackage *clone() const; + virtual bool execute (const MWWorld::Ptr& actor); + ///< \return Package completed? + virtual int getTypeId() const; + ///< 0: Wander - private: - int mDistance; - int mDuration; - int mTimeOfDay; - std::vector mIdle; + private: + int mDistance; + int mDuration; + int mTimeOfDay; + std::vector mIdle; + bool mRepeat; }; - } +} #endif diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 65ca3ae21..24fc58ef6 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -181,19 +181,29 @@ namespace MWScript runtime.pop(); std::vector idleList; + bool repeat = false; - for (int i=2; i<10 && arg0; ++i) + for(short i=1; i < 10 && arg0; ++i) { + if(!repeat) + repeat = true; Interpreter::Type_Integer idleValue = runtime[0].mInteger; idleList.push_back(idleValue); runtime.pop(); --arg0; } + if(arg0) + { + repeat = runtime[0].mInteger; + runtime.pop(); + --arg0; + } + // discard additional arguments (reset), because we have no idea what they mean. for (unsigned int i=0; i Date: Fri, 24 May 2013 15:03:46 +0200 Subject: [PATCH 047/213] minor adjustments --- apps/openmw/mwscript/aiextensions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 24fc58ef6..9f29163af 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -183,7 +183,7 @@ namespace MWScript std::vector idleList; bool repeat = false; - for(short i=1; i < 10 && arg0; ++i) + for(int i=1; i < 10 && arg0; ++i) { if(!repeat) repeat = true; @@ -195,7 +195,7 @@ namespace MWScript if(arg0) { - repeat = runtime[0].mInteger; + repeat = runtime[0].mInteger != 0; runtime.pop(); --arg0; } From d9350be8dac063986e81437d45d15366355bdea2 Mon Sep 17 00:00:00 2001 From: riothamus Date: Fri, 24 May 2013 09:31:56 -0400 Subject: [PATCH 048/213] Console Object Selection Fix --- apps/openmw/mwgui/console.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index cba3412e9..b69d2d6af 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -137,7 +137,7 @@ namespace MWGui void Console::disable() { setVisible(false); - setSelectedObject(MWWorld::Ptr()); + // Remove keyboard focus from the console input whenever the // console is turned off MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL); From 56b1384c90a0a0b5df144d5d6b556a71cc85e1be Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Fri, 24 May 2013 18:16:35 -0700 Subject: [PATCH 049/213] AITravel Cleanup - Removed unnecessary includes and other varius cleanups. --- apps/openmw/mwmechanics/aitravel.cpp | 136 +++++++++++++-------------- apps/openmw/mwmechanics/aitravel.hpp | 4 +- 2 files changed, 64 insertions(+), 76 deletions(-) diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index b22185667..fbae5c1d2 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -1,110 +1,100 @@ #include "aitravel.hpp" -#include -#include "character.hpp" +#include "movement.hpp" #include "../mwworld/class.hpp" #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" -#include "movement.hpp" #include "../mwworld/player.hpp" -#include -#include -#include "boost/tuple/tuple.hpp" - namespace { float sgn(float a) { - if(a>0) return 1.; + if(a > 0) return 1.; else return -1.; } } -namespace MWMechanics +MWMechanics::AiTravel::AiTravel(float x, float y, float z) +: mX(x),mY(y),mZ(z),mPathFinder() { +} - AiTravel::AiTravel(float x, float y, float z) - : mX(x),mY(y),mZ(z),mPathFinder() - { - } - - AiTravel * AiTravel::clone() const - { - return new AiTravel(*this); - } +MWMechanics::AiTravel *MWMechanics::AiTravel::clone() const +{ + return new AiTravel(*this); +} - bool AiTravel::execute (const MWWorld::Ptr& actor) - { - const ESM::Pathgrid *pathgrid = - MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); +bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor) +{ + const ESM::Pathgrid *pathgrid = + MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); - ESM::Position pos = actor.getRefData().getPosition(); + ESM::Position pos = actor.getRefData().getPosition(); bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) + { + int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); + //check if actor is near the border of an inactive cell. If so, disable aitravel. + if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX*(ESM::Land::REAL_SIZE/2. - 200)) { - int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); - //check if actor is near the border of an inactive cell. If so, disable aitravel. - if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX*(ESM::Land::REAL_SIZE/2. - 200)) - { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; - } + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; } - if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) + } + if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) + { + int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); + //check if actor is near the border of an inactive cell. If so, disable aitravel. + if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY*(ESM::Land::REAL_SIZE/2. - 200)) { - int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); - //check if actor is near the border of an inactive cell. If so, disable aitravel. - if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY*(ESM::Land::REAL_SIZE/2. - 200)) - { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; - } + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; } + } - if(!mPathFinder.isPathConstructed() ||cellChange) + if(!mPathFinder.isPathConstructed() ||cellChange) + { + cellX = actor.getCell()->mCell->mData.mX; + cellY = actor.getCell()->mCell->mData.mY; + float xCell = 0; + float yCell = 0; + if (actor.getCell()->mCell->isExterior()) { - cellX = actor.getCell()->mCell->mData.mX; - cellY = actor.getCell()->mCell->mData.mY; - float xCell = 0; - float yCell = 0; - if (actor.getCell()->mCell->isExterior()) - { - xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; - yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; - } - - ESM::Pathgrid::Point dest; - dest.mX = mX; - dest.mY = mY; - dest.mZ = mZ; - - ESM::Pathgrid::Point start; - start.mX = pos.pos[0]; - start.mY = pos.pos[1]; - start.mZ = pos.pos[2]; - - mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell); - } - if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) - { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; + xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; + yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; } - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); - MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + ESM::Pathgrid::Point dest; + dest.mX = mX; + dest.mY = mY; + dest.mZ = mZ; - return false; + ESM::Pathgrid::Point start; + start.mX = pos.pos[0]; + start.mY = pos.pos[1]; + start.mZ = pos.pos[2]; + + mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell); } - int AiTravel::getTypeId() const + if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) { - return 1; + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; } + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); + MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + + return false; +} + +int MWMechanics::AiTravel::getTypeId() const +{ + return 1; } diff --git a/apps/openmw/mwmechanics/aitravel.hpp b/apps/openmw/mwmechanics/aitravel.hpp index 52b41850f..6eb9af8ce 100644 --- a/apps/openmw/mwmechanics/aitravel.hpp +++ b/apps/openmw/mwmechanics/aitravel.hpp @@ -2,6 +2,7 @@ #define GAME_MWMECHANICS_AITRAVEL_H #include "aipackage.hpp" + #include "pathfinding.hpp" namespace MWMechanics @@ -25,10 +26,7 @@ namespace MWMechanics int cellX; int cellY; - //bool isPathConstructed; - //std::list mPath; PathFinder mPathFinder; - }; } From 1e7cf4ae1c3fd90ebace6f0de1e34fe9387be1e7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 25 May 2013 04:15:24 +0200 Subject: [PATCH 050/213] GLES2 experiment --- apps/openmw/mwrender/renderingmanager.cpp | 13 +++++++++---- extern/shiny/Docs/Materials.dox | 2 ++ extern/shiny/Editor/Actions.hpp | 2 +- extern/shiny/Editor/Query.hpp | 2 +- files/materials/core.h | 2 +- libs/openengine/ogre/renderer.cpp | 1 + 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 9061f8402..a5dc8ec68 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -64,13 +64,16 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b { // select best shader mode bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); + bool glES = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL ES") != std::string::npos); // glsl is only supported in opengl mode and hlsl only in direct3d mode. - if (Settings::Manager::getString("shader mode", "General") == "" - || (openGL && Settings::Manager::getString("shader mode", "General") == "hlsl") - || (!openGL && Settings::Manager::getString("shader mode", "General") == "glsl")) + std::string currentMode = Settings::Manager::getString("shader mode", "General"); + if (currentMode == "" + || (openGL && currentMode == "hlsl") + || (!openGL && currentMode == "glsl") + || (glES && currentMode != "glsles")) { - Settings::Manager::setString("shader mode", "General", openGL ? "glsl" : "hlsl"); + Settings::Manager::setString("shader mode", "General", openGL ? (glES ? "glsles" : "glsl") : "hlsl"); } mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); @@ -93,6 +96,8 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b std::string l = Settings::Manager::getString("shader mode", "General"); if (l == "glsl") lang = sh::Language_GLSL; + else if (l == "glsles") + lang = sh::Language_GLSLES; else if (l == "hlsl") lang = sh::Language_HLSL; else diff --git a/extern/shiny/Docs/Materials.dox b/extern/shiny/Docs/Materials.dox index 91e9be4b3..d08599a04 100644 --- a/extern/shiny/Docs/Materials.dox +++ b/extern/shiny/Docs/Materials.dox @@ -87,6 +87,8 @@ Now, let's get into writing our shader! As you can guess from above, the filename should be 'example.shader'. Make sure to also copy the 'core.h' file to the same location. It is included in shiny's source tree under 'Extra/'. + Important: a newline at the end of the file is required. Many editors do this automatically or can be configured to do so. If there is no newline at the end of the file, and the last line is '#endif', you will get the rather cryptic error message " ill formed preprocessor directive: #endif" from boost::wave. + \code #include "core.h" diff --git a/extern/shiny/Editor/Actions.hpp b/extern/shiny/Editor/Actions.hpp index e5cb6df6a..1bbdbe5a9 100644 --- a/extern/shiny/Editor/Actions.hpp +++ b/extern/shiny/Editor/Actions.hpp @@ -10,7 +10,7 @@ namespace sh { public: virtual void execute() = 0; - virtual ~Action(); + virtual ~Action() {} }; class ActionDeleteMaterial : public Action diff --git a/extern/shiny/Editor/Query.hpp b/extern/shiny/Editor/Query.hpp index 7aec68488..d98c8c9b2 100644 --- a/extern/shiny/Editor/Query.hpp +++ b/extern/shiny/Editor/Query.hpp @@ -15,7 +15,7 @@ class Query public: Query() : mDone(false) {} - virtual ~Query(); + virtual ~Query() {} void execute(); diff --git a/files/materials/core.h b/files/materials/core.h index 3385e5fac..c15ec6bad 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -58,7 +58,7 @@ #endif -#if SH_GLSL == 1 +#if SH_GLSL == 1 || SH_GLSLES == 1 #define shFract(val) fract(val) diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 7be713796..e699fbbcc 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -206,6 +206,7 @@ void OgreRenderer::configure(const std::string &logPath, pluginDir = absPluginPath.string(); Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mRoot); + Files::loadOgrePlugin(pluginDir, "RenderSystem_GLES2", *mRoot); Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mRoot); Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mRoot); Files::loadOgrePlugin(pluginDir, "Plugin_CgProgramManager", *mRoot); From cc747d8ae4c8f46c789fe024b7c5489291ca9057 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 25 May 2013 04:23:07 +0200 Subject: [PATCH 051/213] GLSL ES: precision qualifiers are required --- files/materials/core.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/files/materials/core.h b/files/materials/core.h index c15ec6bad..d53d8d4a9 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -64,6 +64,11 @@ @version 120 +#if SH_GLSLES == 1 +precision mediump int; +precision mediump float; +#endif + #define float2 vec2 #define float3 vec3 #define float4 vec4 From c2c88acc7b83cf40e3f367dfd8ca50157d570a9a Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 25 May 2013 04:26:40 +0200 Subject: [PATCH 052/213] GLSLES: only the fragment shader needs precision explicitely set. --- files/materials/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/materials/core.h b/files/materials/core.h index d53d8d4a9..e5d58ba25 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -64,7 +64,7 @@ @version 120 -#if SH_GLSLES == 1 +#if SH_GLSLES == 1 && SH_FRAGMENT_SHADER precision mediump int; precision mediump float; #endif From c8c1ddd927525ab3b1d71a7fb365cf8276b94b37 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Fri, 24 May 2013 20:10:07 -0700 Subject: [PATCH 053/213] Adds functionality for checking if the animation group passed is currently playing on the actor passed. This is needed for AIWander. --- apps/openmw/mwbase/mechanicsmanager.hpp | 2 ++ apps/openmw/mwmechanics/actors.cpp | 8 ++++++++ apps/openmw/mwmechanics/actors.hpp | 1 + apps/openmw/mwmechanics/character.cpp | 8 ++++++++ apps/openmw/mwmechanics/character.hpp | 1 + apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 7 +++++++ apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 1 + 7 files changed, 28 insertions(+) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 38794269b..7e09f9b4d 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -112,6 +112,8 @@ namespace MWBase virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0; ///< Skip the animation for the given MW-reference for one frame. Calls to this function for /// references that are currently not in the scene should be ignored. + + virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) = 0; }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 4db574cb8..00f2ac6fe 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -309,4 +309,12 @@ namespace MWMechanics if(iter != mActors.end()) iter->second.skipAnim(); } + + bool Actors::checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) + { + PtrControllerMap::iterator iter = mActors.find(ptr); + if(iter != mActors.end()) + return iter->second.isAnimPlaying(groupName); + return false; + } } diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index c01d63093..386840e3a 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -82,6 +82,7 @@ namespace MWMechanics void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); void skipAnimation(const MWWorld::Ptr& ptr); + bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName); }; } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 31ba83392..c7aeb1b5f 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -509,6 +509,14 @@ void CharacterController::skipAnim() mSkipAnim = true; } +bool CharacterController::isAnimPlaying(const std::string &groupName) +{ + if(mAnimation == NULL) + return false; + else + return mAnimation->isPlaying(groupName); +} + void CharacterController::clearAnimQueue() { diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 7ffefab47..7067176e0 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -125,6 +125,7 @@ public: void playGroup(const std::string &groupname, int mode, int count); void skipAnim(); + bool isAnimPlaying(const std::string &groupName); void setState(CharacterState state); CharacterState getState() const diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index b83cfb365..29880291d 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -668,5 +668,12 @@ namespace MWMechanics else mObjects.skipAnimation(ptr); } + bool MechanicsManager::checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName) + { + if(MWWorld::Class::get(ptr).isActor()) + return mActors.checkAnimationPlaying(ptr, groupName); + else + return false; + } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index f3a38bf36..95f760d11 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -100,6 +100,7 @@ namespace MWMechanics virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); virtual void skipAnimation(const MWWorld::Ptr& ptr); + virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName); }; } From de5a08a07d359841828827f8b72fdc87ca1421c8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 25 May 2013 05:40:35 +0200 Subject: [PATCH 054/213] Version should be 100 for GLSLES --- files/materials/core.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/files/materials/core.h b/files/materials/core.h index e5d58ba25..6f8179c08 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -62,7 +62,11 @@ #define shFract(val) fract(val) +#if SH_GLSLES == 1 + @version 100 +#else @version 120 +#endif #if SH_GLSLES == 1 && SH_FRAGMENT_SHADER precision mediump int; From ddf28ca201a25aa28dac65bf1dcfa0f349923ab5 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Sat, 25 May 2013 04:36:21 -0700 Subject: [PATCH 055/213] AIEscort Cleanup - Fixed spacing, removed unnecessary includes, fixed branch itself. The other pull requests were fine, it was just this one with the problem. --- apps/openmw/mwmechanics/aiescort.cpp | 48 ++++++++++++---------------- apps/openmw/mwmechanics/aiescort.hpp | 23 +------------ 2 files changed, 21 insertions(+), 50 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 7c28dd216..5b94c4938 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -1,6 +1,5 @@ #include "aiescort.hpp" -#include "character.hpp" #include "movement.hpp" #include "../mwworld/class.hpp" @@ -10,16 +9,12 @@ #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include -#include -#include "boost/tuple/tuple.hpp" - namespace { float sgn(float a) { - if(a>0) return 1.; - else return -1.; + if(a > 0) return 1.0; + else return -1.0; } } @@ -77,11 +72,8 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) { MWWorld::TimeStamp current = MWBase::Environment::get().getWorld()->getTimeStamp(); unsigned int currentSecond = ((current.getHour() - int(current.getHour())) * 100); - std::cout << "AiEscort: " << currentSecond << " time: " << currentSecond - mStartingSecond << std::endl; if(currentSecond - mStartingSecond >= mDuration) - { return true; - } } ESM::Position pos = actor.getRefData().getPosition(); @@ -91,28 +83,28 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); - if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) + if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) + { + int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); + // Check if actor is near the border of an inactive cell. If so, disable AiEscort. + // FIXME: This *should* pause the AiEscort package instead of terminating it. + if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / 2. - 200)) { - int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); - // Check if actor is near the border of an inactive cell. If so, disable AiEscort. - // FIXME: This *should* pause the AiEscort package instead of terminating it. - if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX*(ESM::Land::REAL_SIZE/2. - 200)) - { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; - } + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; } - if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) + } + if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) + { + int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); + // Check if actor is near the border of an inactive cell. If so, disable AiEscort. + // FIXME: This *should* pause the AiEscort package instead of terminating it. + if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / 2. - 200)) { - int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); - // Check if actor is near the border of an inactive cell. If so, disable AiEscort. - // FIXME: This *should* pause the AiEscort package instead of terminating it. - if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY*(ESM::Land::REAL_SIZE/2. - 200)) - { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; - } + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; } + } if(!mPathFinder.isPathConstructed() || cellChange) diff --git a/apps/openmw/mwmechanics/aiescort.hpp b/apps/openmw/mwmechanics/aiescort.hpp index 667b88e31..3ae604035 100644 --- a/apps/openmw/mwmechanics/aiescort.hpp +++ b/apps/openmw/mwmechanics/aiescort.hpp @@ -2,30 +2,9 @@ #define GAME_MWMECHANICS_AIESCORT_H #include "aipackage.hpp" -#include "pathfinding.hpp" #include -/* From CS: -Escort - -Makes the actor escort another actor to a location or for a specified period of time. During this time the actor will also protect the actor it is escorting. - -If you are not doing this package with the player as the target, you’ll want to also put a follow package on the target Actor, since escorting an actor makes the escorter wait for the other actor. If the Target does not know they are supposed to follow, the escorter will most likely just stand there. - -Target: The ActorID to Escort. Remember that since all ActorIDs share the same AI packages, putting this on an Actor with multiple references will cause ALL references of that actor to attempt to escort the same actor. Thus, this type of AI should only be placed on specific or unique sets of Actors. - -Duration: The duration the actor should escort for. Trumped by providing a location. - -Escort to: Check this to use location data for the escort. - -Cell: The Cell to escort to. - -XYZ: Like Travel, specify the XYZ location to escort to. - -View Location: A red X will appear in the render window that you can move around with the standard render window object controls. Place the X on the escort destination. - - -*/ +#include "pathfinding.hpp" namespace MWMechanics { From 2850032d9e442f77cec9e6ebac90ac09bd645db8 Mon Sep 17 00:00:00 2001 From: eroen Date: Sun, 26 May 2013 10:36:17 +0200 Subject: [PATCH 056/213] libc++ fixes: avcodec/avformat workaround With libc++, string includes stdint.h, which breaks the fragile avformat.h workaround, which depends on __STDC_CONSTANT_MACROS being defined before stdint.h is included. Moving the string inclusion after that eyesore shouldn't break anything. --- apps/openmw/mwsound/ffmpeg_decoder.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwsound/ffmpeg_decoder.hpp b/apps/openmw/mwsound/ffmpeg_decoder.hpp index 32b2797ed..a5e5b5083 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.hpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.hpp @@ -1,8 +1,6 @@ #ifndef GAME_SOUND_FFMPEG_DECODER_H #define GAME_SOUND_FFMPEG_DECODER_H -#include - // FIXME: This can't be right? The headers refuse to build without UINT64_C, // which only gets defined in stdint.h in either C99 mode or with this macro // defined... @@ -14,6 +12,8 @@ extern "C" #include } +#include + #include "sound_decoder.hpp" From 886bc7e2f6563aaa6bd01608991dfec54a95a488 Mon Sep 17 00:00:00 2001 From: eroen Date: Sun, 26 May 2013 12:44:10 +0200 Subject: [PATCH 057/213] libc++ fixes: don't rely on tr1 libc++ doesn't ship tr1, but ships unordered_map as it is part of c++11. Since this is the only tr1 header used in openmw, add a check for c++11 unordered_map and fallback to tr1 unordered_map if it's not found. --- CMakeLists.txt | 6 ++++++ components/files/configurationmanager.hpp | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b989297b3..43415c953 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,6 +181,12 @@ if (UNIX AND NOT APPLE) find_package (Threads) endif() +include (CheckIncludeFileCXX) +check_include_file_cxx(unordered_map HAVE_UNORDERED_MAP) +if (HAVE_UNORDERED_MAP) + add_definitions(-DHAVE_UNORDERED_MAP) +endif () + set(BOOST_COMPONENTS system filesystem program_options thread date_time wave) diff --git a/components/files/configurationmanager.hpp b/components/files/configurationmanager.hpp index 9056e792d..765f1cebf 100644 --- a/components/files/configurationmanager.hpp +++ b/components/files/configurationmanager.hpp @@ -3,6 +3,8 @@ #ifdef _WIN32 #include +#elif defined HAVE_UNORDERED_MAP +#include #else #include #endif @@ -48,7 +50,11 @@ struct ConfigurationManager typedef Files::FixedPath<> FixedPathType; typedef const boost::filesystem::path& (FixedPathType::*path_type_f)() const; - typedef std::tr1::unordered_map TokensMappingContainer; + #if defined HAVE_UNORDERED_MAP + typedef std::unordered_map TokensMappingContainer; + #else + typedef std::tr1::unordered_map TokensMappingContainer; + #endif void loadConfig(const boost::filesystem::path& path, boost::program_options::variables_map& variables, From b31f0dfe1f42cd6aa42592cf4a513d7e9e2998bc Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 26 May 2013 17:28:27 +0200 Subject: [PATCH 058/213] Raster status icons. --- files/opencs/raster/book.png | Bin 1442 -> 1336 bytes files/opencs/raster/ingredient.png | Bin 1624 -> 1444 bytes files/opencs/raster/light.png | Bin 1069 -> 747 bytes .../referenceable-record/activator.png | Bin 0 -> 2297 bytes .../referenceable-record/apparatus.png | Bin 0 -> 1864 bytes .../scalable/referenceable-record/book.png | Bin 0 -> 1336 bytes .../scalable/referenceable-record/book.svg | 33 ++++++++---------- .../referenceable-record/container.png | Bin 0 -> 929 bytes .../referenceable-record/ingredient.png | Bin 0 -> 1444 bytes .../referenceable-record/ingredient.svg | 15 +++----- .../scalable/referenceable-record/light.png | Bin 0 -> 747 bytes .../scalable/referenceable-record/light.svg | 25 ++++++------- .../referenceable-record/miscellaneous.png | Bin 0 -> 1518 bytes .../scalable/referenceable-record/potion.png | Bin 0 -> 2019 bytes .../referenceable-record/random-item.png | Bin 0 -> 1612 bytes .../scalable/referenceable-record/repair.png | Bin 0 -> 1474 bytes .../scalable/referenceable-record/static.png | Bin 0 -> 1518 bytes .../scalable/referenceable-record/weapon.png | Bin 0 -> 1465 bytes files/opencs/scalable/status/added.svg | 18 +++------- files/opencs/scalable/status/modified.svg | 20 ++++------- files/opencs/scalable/status/removed.svg | 20 ++++------- 21 files changed, 46 insertions(+), 85 deletions(-) create mode 100644 files/opencs/scalable/referenceable-record/activator.png create mode 100644 files/opencs/scalable/referenceable-record/apparatus.png create mode 100644 files/opencs/scalable/referenceable-record/book.png create mode 100644 files/opencs/scalable/referenceable-record/container.png create mode 100644 files/opencs/scalable/referenceable-record/ingredient.png create mode 100644 files/opencs/scalable/referenceable-record/light.png create mode 100644 files/opencs/scalable/referenceable-record/miscellaneous.png create mode 100644 files/opencs/scalable/referenceable-record/potion.png create mode 100644 files/opencs/scalable/referenceable-record/random-item.png create mode 100644 files/opencs/scalable/referenceable-record/repair.png create mode 100644 files/opencs/scalable/referenceable-record/static.png create mode 100644 files/opencs/scalable/referenceable-record/weapon.png diff --git a/files/opencs/raster/book.png b/files/opencs/raster/book.png index a011f351489ff87d930331e2a353bb1b805eb504..3afa9e8aae15c8d494e6e6e338890baffde4cec7 100644 GIT binary patch delta 1116 zcmV-i1f%<+3%Cl9lz#|GL_t(o!|hgWOj}hLes1rjr9h#yKw91Ss8K#L2MmTYaZpfV z&{zv&EsMj%n9Q+EGXI!qBAJ@NlEo~JsJOUIvyhC$m@Fgn&;Bh_6N8OnR2U46$N*bh zX{n{9=k>?EZErsZE@@2M`{$nXoRjyw@AEw8-V5B1|9fzo-G4YVG+0GoU<3dJVhjKh z=U@N<%gf7aBOjjq{cd@M%^W^{b^Pkg6&xW9f^ZO8c&BM9XK*=jZ1f30Ht^D9_caN*#qFXF=K zbASS{zF>vp+J6Lc^Ky}|&qrsMb@wi!xmGG{45ex+UpM3mj-RQ;9 zsVy`ndpj%^%g#*~aJ2vE(@(ay9Uw>!2O^z@ zpNzz77k{0H*AsC~exAzO{oF{hv-o(xY&NU++xC4?R$5jZ?kw6-Y{zmOGKN^fK7vlK z+paCt&VGI4n;+6LP+3*kv%9J35lW-|W;`L{(R~1+zM<}Pb91vUT>+fE$2Oo;X7TbQ zjN-Hp<7u>~B;F}4-BwhyqjDgn1jEDcpK38TKYx=nnOu8 z+1WW?3A4%CRK$#wLmNNGwB%-jN$t z#D4?@*XZ-EU*H=W8iXT#hi{lnCQVd($cz-dT1bLZ93KC&iZBo-hqh2#ICpDqQ79=f z?sGaoozU-)Cy<8gl$2nMyn zswdD=T~!T(!GKIfmc!w;+wJ`TAh^AuMt_du6yd5f5y4^6R>03wzbgOs=e`Y~kJA*jTx@-!qN}!cXAXd* zzbG*fm--(jVI{@hnc3ekc6s`aQMXvl8MoK<{^@z}6oK2w7zI-3bC%9=<>loHj~U-! z%Jks?kR|vt-t_(W@5MjS45#O@Cg;SH4+R<*H7znWR53R?GB-LhFe@-JIxsLu#te3o iKm{5XH7znWR53R?GB-LhFe@-JIxsLfo3zT4aRo8!!6V23 delta 1290 zcmV+l1@-#43Ze^;lz(zbL_t(o!@W~oOj~6beh%l9vO^F3qfq`zVF4rzl**g~oCL#Q z*~G#|fEaNwHHsG|MsH^Hf@y+5V=z(Xm5DbdF42TI=fVOy`B~!BAVv)xVAKr>e}j$M zLi@d5l(wh8RE2)Y$@$K6-tT>$_j%us!w##gtc*W->f}(GHh;BrU(AVwf! z00%H)AVyeQy^Z7)2_OdMcGKAC#FOv8cm7he{QOP=jvZ^LIdi7-Z2wDdNt4r4qFO15 znZ^w9+BXy8Z@x^$reS7=OxCBr1@bYl11q1lyDireZU$ema8vr3J7}P9rbRjPc=dq-Z6~OwZu@ z*WaSPsX=>ZeSPh_>)%gA%Fjh3@9XP*xwXBmcgwYvaO;m-P%0CVo|z6tgxTpCs8S?o z^%~eW>{$G35ytFvIGj$nwp?(#TmT2Gtgim~PXD__BY$6x*#DISot>Te9j7}!QK?jk zJkLX|RU=uI3?hISgGQ@C(!L}R5qO@5q?P~>1fB;k2v8&{AP52^NtGfb2%4eGSHjLh zLL>o&MFnr@Q}rSv<{3I70G`1k0F20oQxFar&WPb~)uHaTC)z4w7GSkn3mYX)YDxb==FM$h-4M9kct7wDvgd; zJYcaDm)ujoqkx`sJuQ|BOAQ6sD7QJ#ULUEd!-SaJtIkU8LwljDqqIzb?)Bvq0*H|Na| z0Vf`_4rFC#rOB^cEWM976H(4r*Hkvt9<43&33#^qnfm&pb?w1}RKV zFn?E+7(tR$N!F(00|3C6mzNu?O-*BkMFokGd(Q%{VlW=_Ovuh_^_m<>l5Pn3`FRf| zaGdhzpMC*(F0e-#bNJo?1ME4sw7g`WpTBuwadFu!+?-#p z&(GWM*6DN##A!M0KQ2G_+ViIYK)7RfTYn4&17|Q8;>8b}?S|637o1LxpPZaxCR29Y z1kBF;uJsAnu)A4CMh1*VW84HtDO!alz53kkh0#}qyLOr#yf}LA!HNTM6Y#_2H10ap z9mcHtKjsXX2fNoCx_)t=QuzO=V_S?79F8q#a?;v32LNWX*|eJkRSt*v`qI*i!GHLi zAYAD(8n4Nq%{{4*0No})!H*N@369-0+cyD=ckcpp;bJ(zERW-WB`%iaF$(w$K&?MF zqzIww+wUa~cwx8ry&{IfSs(7%0@`<#Tqfdj4CJkQLM{_=DT;uWJtdckxEO}~R9whq zA_isT&2c4{i8#LrSR?)a2j=3_9Dn6xuYLdk03~!qSaf7zbY(hYa%Ew3WdJfTF*7YN zGc7YQR536*Fg7|hGb=DMIxsL^wexTQ001R)MObuXVRU6WZEs|0W_bWIFflVNFf%PP zF;p=yIxsdmH8U$PGCD9YFX&6m0000PbVXQnQ*UN;cVTj60C#tHE@^ISbCVzi7*)Yp A-2eap diff --git a/files/opencs/raster/ingredient.png b/files/opencs/raster/ingredient.png index 6f9a09d2e93d64c118e7d375868068f77a2b0d02..6b36d008d26b94b7c0c1f1c2d6f215f24ca08c94 100644 GIT binary patch delta 678 zcmcb?vxIv>E~E3tJatCn!fA#L%WSI`SQO7NshDq3wa~I~no;R&^X^R^mGdl$XPFgF zH)>hs)U(N>VVQmDY_sAShLe9Vs)&}(GAWy5UOL;fXu4_XEYq?XX2nwsC;Kzaocx+e zn&aG&xLgJXhSte^%&8hu&wsid{%O$j@279Uzkl!7iZbT@{`KhEy*JNJ=LyXH^U{aM zh$B1mT*&0D%&LqtC*Nk4tk2HPe*ZxHfSRs`iq55*SMT1vds(~7HOePu(Ryi~U%yp0 zp78cO?XYCGy3drU&eNxc2h3ra`tIHPkRZ3|;enyep5^}YF0EbHsJ4FPRle!-t=8_2 zj%E*y3(vQTsXKP&U0yA7NTsuKOU>^!@7~=!rl#>}Sz2*Jf|Z2N9B!2}x&cq>b=O)6 zCdB_3~Z3{}{O!COlo$y4q1;0;j8Ez=u_# z#tsQ*qYO-yRYXih4*$5`cwklJ-_-{esMp&tg*v8O`Sta+c}~QhLS~LLcSK~H#riiE z&TdHf_{=w9gQ^{)t)hxr?%iFbXScnLc1S2H;&QV}_5t#*^{q`Xu+)|H_Bs=>v-tYE zyOSFgjJ2h^ZJhny&D&f3{q61f)8hj=Tz9S5v1H4dJ&QK2+Oo=Ijdcx7b&bqI49%^KfXGPO vz{twL;C`fRJc@?g{FKbJO57UOu`GQI)F276Aviy+q&%@Gm7#pHC7V0|^<*fd delta 820 zcmZ3&eS>F0F5{GqdFqVG{}~v5F);jOU?`ks*s#pDdVxjp3=^OrP^4nMMb$#f!f8f8 z1;4?{fMn@x^X^R^mGdl$XPE)T;Rq;IINhjal~d0qkA`LTrL)b7XBa{>PCmh?VhmxH z&N3;RV_rJjv}n31L~H3R)3O<6#Zy3P(a>Z@rkTt@vB|TTq&e<%MYA(7FwCF4mnqeW zy~9rG`A;{Yro%rCj9eDU_5AzkyZ+;+yFLZ~{=Hu-x;v6F_xGRd{CB&0p9>EJ2RNfA$$E=g6m7XxE;uRZ>1xFK?B4 zUp2k(#B{6Jp{LjLBX)&Evxmlo=PSq5U4FLI`zvq2Q{G;IPu$yqhF`tG;(G5&jwV`IVBSGm{BPJG%{W?g>p;3;42h6DE)BO4cAcCxs!SIEb5 z@r?(Y68UA`uufi=cjD7KIcbH2`}=Bte{Vd%=C7Z^de4r%;ei5&4AW%x+P?ugANX(Z zvbOiXvEyQD^wHpIYU-D{$-;EJuX&}f;=&aRC63iIvGnCc)>pFdOlx&tpw-c1Rr%@3 z%HV4M`Am&x(-$RQcw}hyjz{2)Z8aOuxufa^1}bWe4n`r4Uax+Be%>Fuqk@m++Onn0 ztwwr{4r(Ec$=7~CJ1Y}de>#LQdbmD(s2#pOHkzBo^{6Tj&(hS? zrwOdnPo2`za^zaIYJJH49fhBtt(|piSCzp2he9$YOgnwg>aNXwD?2y#uI=6c@81cZ z{wmyS>71;#Sp9*fz|WNl=eE2wmM}QrGvSX8n@z&ErQXF7ADVW4Rxn{;`fhLUTKy$u zvLLIJhq11)VThrDm4TU+sfo6Mk(GhLY@xINfT>8e#5JNMC9x#cDmOnRGp&-r$iUE8 Q*8q!#SN^3=lZ#mm0a)N+Pyhe` diff --git a/files/opencs/raster/light.png b/files/opencs/raster/light.png index 5cfbb1245cda2e6c35f5c3ae7b40675097e85a32..c606fcd98737296fdd6d642e343e95f50108ca58 100644 GIT binary patch delta 530 zcmV+t0`2{+2Zbqr-v9Nz|KN@P=5+ntasS_t|M=kl^}he$i2vho z{oil@-i!bJ=>PW1|KW}Q;&A=mZvWqp|NrX$_~ifNp8n>2{eR+p|Kgzk+c)~vK;yzd z>(GAe(SqW^KKs)>%d9f}*hT%>NB!AI{M=jp;d1@wkN@Cq{pEtbp)a_bH@TcS_0mYr zu|3VOJN(;O{oro=UUX0S2Ig0R~-4v;Q?YaKzxhj|<=%p7SEqjvx>&lIry- z68>psFdU5;8U!pina<`M3j$tPELUrR2Z1PUw!6I~faV7>Hq)$ delta 897 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 NpsdiyY739J{{rAiJ1qbJ literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/apparatus.png b/files/opencs/scalable/referenceable-record/apparatus.png new file mode 100644 index 0000000000000000000000000000000000000000..b13982d091fabdfdd498577752844e8342e9c32a GIT binary patch literal 1864 zcmZ{ldpr~R8^^!1VQy>PFv4<(xixl<3-qD^@^p7nQPfZb0I0Y) zlgLt{_Yy8At0$&=XXQmEcH$clrWdBxm-ejqrN-2|K)*t4U%DD zk)nRKo~L~lny{FS46}flu-19L#*F(VS&0wOgc!t+Y4_f;MHsG#4^oAAyGf_Q70Y8TeWd5{a$194nDe&a5mE9s;0 zHFVx2QXGwCP4x@Oc|?a>>!Hf2tnrdB4{qqEH>iGOG8eb2z2>S#qW% zwecIZgJu_ZUSBjYX!s{Vux@8j&hT9?m-nEryAtT5XW z>UPw%?c;RF%;&5hZQ_oo`1pRItJoj*QsfQ3r8v4M=)=&k5>zg{2;Ql#j-k07WU7{) z4rpJ91orcqt&Nmud#j|zs15PimL$nBTXx>!H+4e{v)}-cHJq$V8YC)00+dTo8|M)o z^?(tNc$3-ZUdk!RZqvFWrey9B2sR_C7h=*>%eSD}n z1j}MavkK-R8NV@RmTn1_G<>!FKpX0y`9duZg3z)1_s7n!nlS2P*@JCwLh`$(JU`Sc zjGQjZ>lS_qwTPS^)K!+r=;?tMP=!br1pxQ;xg9s3!-F(VOWp|UMhH<)Xf;R~;wyJS z)nq0a;DUxqolCv+^mXY%e!`a*4|yP0%jVc~N{Xz*r;)x&Z^I7Y;(Qd%&Umju#(2Kl zH@a5kk=9W3VqjqCX3b2&Gm=U)tp6$J^xQ zNe80>tD_BaRbO9MDg`D)_ETtP{P>-gSq=<8wrf%%i! zQ~j6Pak=YI@0x+zs)5XC#F;~tBVoN8hFkEAsO zoSnS8bRU=K2#!wKb)S#vYg32PO^seoWIMLEUo0fYS$NcWXhn4UwT;p*p|0up8{Nwn zG}UR!I8)Vd#&HOS4*(Y}U)d5uSY7+zg817B#T1>I;-ZLOPy%w%ly8sGI2BN54S8P)Gpq=^0 zrPrqbFzD)h0^(bYpS{rVH_;zz2E17Q=4>up{SKHnP+nNst%+CbXt3+>xUM(xGm`Hw zKVG9#Eo}`XvFul#u^5Ey-`%!*boNwixK-2OW(u$s*Xva+QwyYrLqF!Hb1^{yF~Qcf zs9-681=bvAiv7XV!qVIPgtdhHh`i+)?cS literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/book.png b/files/opencs/scalable/referenceable-record/book.png new file mode 100644 index 0000000000000000000000000000000000000000..3afa9e8aae15c8d494e6e6e338890baffde4cec7 GIT binary patch literal 1336 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UV>C6dj$D1FjT2AFf_Cwy$!fk$L9(CXhH%*b7CIvZ#mho_5UNW|f{VYxohp%Qg@@0TuhSh&R@ z>h6yffp$jhJZ;8>0Rc%DBDj-vyAL0kab}~B(f=8lN;792m~>R9Z^e!szMCiX9GRh` z{Q3Mp-C*J7-lPx-p57A-(J`4Tmo9z&_4wZ0e0z4iOrJZypU?X|XY%(w??2l-zsG&2 z|9^GC?7J2wCK0X)2`mgONjwZf&l4CJPoF-Wtt>z9@87)2*0VBpb)|n^oq2L)-OQJ> z4Me09Ei)LEnUvX*E4@Juv-7op_j!COdIwkv_8JYQuMiK;`;OM>C;PpTzU~v zy6aC@Nq25;?yTeA-&lS=xI6v9^Xm)4Rwm}<9}SO>Yrp)oDf=Yn{NvrXKXc#U$b0b2 z|MHEy|0JeOoAzMGKUpqru2p_}j6Yo4|Lwp>^Ei2{Z?`r+?lCk-O6Y0qI1s_%(jt(o zz{$_T^q`W}X`#TM*RKP#rhZsgDaga}XMW9}%)2j+UR$*)`puo`o>BE94;&k z4o4gqB2x6$aWnBVG4wTiEoBjGj+)zR;~V$QdD*7P(bE=OPWpS|N5e)56|0yxF;)`{ z8#E4aoGj=%?AWq*ZMC(I*y(e=;ssm&zqstbZM&?32OqoA+_w2WN3zA|wqF-6^sSqB z>ek;o9-B7*s5p>gw)*?+Z?%D8QDHLgbZ!Oa950eFYKu5z*W|bU_B!1w=jv)7&z8Sr z6c8DDbMx+%F9p38|4p+|d~~svVd1`o?@Ee`H|xbR&e?n1Y(Yrc$4@FfkGAkX&fKzG z<({VQ-LR0&i;EPNvK&7Aetwprx&365nK9K(9rs;-SEzBc2swW|{7&@y&zmZX%Va&lI^x4CdTxzpo9?)$n`?@wswb45mSeLS^M<;yX(&aWOi&YkxrN{1a` zVZHw1^Sby4(o#|_%C+tJGkny1L#j{oi0qB>XbP5*`@gBnKtR2HTR^l$d3Ii)hNj`W zVykcy;ro6Ln*^8mTQRJZ$P|0&VicWn=1@5Aqq<4Qf|Lx~XUMwDi2sp%^>Jan7zf+d zL#xy;1jUB(HXm&8ah-Pf;kMgv|1v1-*t^iJ@3F|kRmOq`69Po#xU={1EHO#K zlZw3yt1qs+n^v_Y<=?d@n;v{?shGR3MN3P|DD1%b;Qdh!%$%QFL|{@)uZ=j-n?&6R{5(haC^jA$?ey_{(D*ZL8S5a2?^Gq7sb=g z6+V6Xl&k-K!l^G0878RyFuwQY?~nIK?Jx2yf4))e`4M12p<3b^QIe8al4_M)lnSI6 zj0_Bobq!2)jm$y}&8>`p$Uxh`$jZRL;}}mFiiX_$l+3hB+!`!rZ#f0jAPKS|I6tkV oJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<-Pgg&ebxsLQ0QSUK-~a#s literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/book.svg b/files/opencs/scalable/referenceable-record/book.svg index 8c041a9e7..56c8e6c6f 100644 --- a/files/opencs/scalable/referenceable-record/book.svg +++ b/files/opencs/scalable/referenceable-record/book.svg @@ -23,18 +23,18 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="1.4142136" - inkscape:cx="-144.10221" - inkscape:cy="10.836112" + inkscape:zoom="8.0000002" + inkscape:cx="52.294682" + inkscape:cy="4.9257181" inkscape:document-units="px" inkscape:current-layer="g3891" showgrid="false" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1280" - inkscape:window-height="994" + inkscape:window-height="1001" inkscape:window-x="0" - inkscape:window-y="30" + inkscape:window-y="23" inkscape:window-maximized="1" inkscape:snap-page="true" inkscape:snap-bbox="true" @@ -514,7 +514,7 @@ y1="1067.036" x2="37.487514" y2="2532.4438" - gradientTransform="translate(-1.6900304,-354.84909)" /> + gradientTransform="translate(-1.6900304,-2.3597835)" /> + gradientTransform="translate(-1.6900304,-2.3597835)" /> + gradientTransform="translate(-1.6900304,-2.3597835)" /> - diff --git a/files/opencs/scalable/referenceable-record/container.png b/files/opencs/scalable/referenceable-record/container.png new file mode 100644 index 0000000000000000000000000000000000000000..e54c69af89e72514d9fdcd6e77049e4bb4a85572 GIT binary patch literal 929 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D+_~q^pWnWH z`{>c5nVFfhX3cu|@ZqCJkARA2&z{XEVaYDyK4;$Y{RfWk*>`mJo+ESTuV5DNRn(14 z&Z*@Vb!O!EXA|<^mGYL;2$a(ZlGg}U&$k5r@7%cm;r*TW@1A}A^5Waqm*2j<`u6qFhxgAvez<<~>ZfntK7Rl9 z;rsV@-@m{8_VxAGuP?uTxpwpF(`SkHow3AapG0l_x0r#5ep zTEu8pmQu;*=ffIvhoe$1&aRG!HHWFGfYs@cQiMoHmt)FNRTY)qB};lQHuUstT+`BG z5fJAWcksxSGj|SMI(6&VwR89Gox67I)~QQ}?i{=l=osfW$1(8a$(u*7p1phc^6A^h zub;nv|NQmiw@+U_eE00tqc=T0C!XVCVrp)3c4}&7VlL3&;N|Y`=;`X~&she8Y=p< z(eK0;CWgkyk}}?R-{t}Rs#@Y2QIe8al4_M)lnSI6j0_Bobq!2)jm$y}&8>`p$WYtB z$jZRr-A499C>nC}Q!>*kach|WW`7+}gCxj?;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7 V^x5xhq=1STJYD@<);T3K0RW8?x7h#y literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/ingredient.png b/files/opencs/scalable/referenceable-record/ingredient.png new file mode 100644 index 0000000000000000000000000000000000000000..6b36d008d26b94b7c0c1f1c2d6f215f24ca08c94 GIT binary patch literal 1444 zcmZ`&drZ?;6#nsWJ`m#;e8F&RBDz7f^g(Gwq4YruZ7rn;sKFwy8CEH6p_Ga%LP5&= z*>@=hQK5h>h)_@~Ai9Vqx~VY^w>e?rq-@Kkw6)zX*~+9HIotN zyUu?d1VO%33XuhJ(8^xp1tPIaJ`Iw0E}o8uAX9_S`;1kf_7Je*Vxj)~A1|yRGbt=O z1eJt9khB7V9N;s6t9F9FQ4f zi`!vE>WHd-g2KuYY0zRFre-j%q8AS&73nec!&KG8O1nUXsv00RjwFC7Km#~AJ3tbs z5I|?$5LI#xD>h((NWK!qYe!TXV^4QQNu@C&ZA8r=rDcpE(qW1_A{(#LO1t&}hK8#N zauc~gfhf|V0Y=&r3L@YEv<2;mLQMo9|N4BCK#eMB50`fDmlz@iN)%uy>HHUfsWDT; z`bdE~0+3Yn#MYWA((Y)`C{Tt2KZPn(u?{2Y+*e}2oigBnQ4$ahI51kMLGcubLN%&L ziz(Eg`3iKQ8eOD}5VVH3UuP<VoNvF8sG3Ns9il34 zCdthdg*6fQEH}pi{cYEniW`Z*pJofA^%}Ef>|hHZ8CtQc+C*-)(3?i-RRg3Z3%#aI}1^SM8j&IL&(WHFLJ-kvVIFmC!{Z%Mt~?jm|?9WLc( zIdASY*@Hq$BW0$-^|}Vxl#9i zfwms8Chx?3HW1=*JRyzp&(?_$jv)_iwNr!1i&kY2ucQ}JhcM_;~W4gw6 z(OTOGinbJ{*1OGSTVk`wij>6Ua;oT{{$XE#S;)YpM;jC!xW2I?M^-1Nr{v>~o}Qku zoh+tcZg-G6lF2&5d`R+`o)cm~FN3G2gs$VqojRSS&V#yRfd{9b9f zds}G?XGvQ6+&t!bocaFb)#e9`IUf{K6=6k=u^34sV0*#dO`#hat4bLJjP_hwB|rNvQ6{@|41(x|Mg8-lW2FJ1i0zIVXQ?G%zyg;^QGY+NQk8zcw; z4@bh_Xc!`b9ge{vz(Rz=5jZ&fhqS - !lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!Dss^Zy@@{=eG)|JtPgpN{?i`||&{Q~#eY{CBJ7|LwZ} zua^D)aqs`vz5gHd{(n~T_io|;`xE~Ec<}%0zW)z8{y#4Gdq4mGz3%^iU;O`e`v1e; z|Bnj(-pl)czyJULSO0%J`Tuy{zh||7AJzVUwBY}3^IumT9v^aeeWC8n#imCG?S5aj zJ-x>0?+w?#H{Ji<^!Rfp`tQS{zt8*sKgj$0v}xZ${T;K-ch0f=ddcJ5M%%L+tpD7O z{QDs9&y(iA4@>_(p8)hudYNSnkg_TX@(X5QU>38oW6=uPxhYsKaPr4D-TE2({{G#q zmwxo$-y_ogoBsaYz^qpD`*#)d^vi$$UXJ(@7Z*6~)^k4TvPuR!pec+=-tI089jvk* zKn`btM`STDW`2V(BX_y!Y@pyAPZ!4!i_>pUxk@z!NVGoW){sbOU}Rg+#K;!wwfVoP zWx#mQ{&{c%6UuqIPNT3vuaa; z;exzbyO?Ev2v^uYXk_^5D8XiTNaSeYmAHKYp$6@oi!yY9?o=&tjVMV;EJ?LWE=mPb z3`Pcq#<~Wkx<+OphUQjAKxCwCU}R-ra6eKu9z{cLeoAIqC2kGtSe8BpYLEok5S*V@ pQl40p%1~Zju9umYU7Va)kgAtols@~NjTBH3gQu&X%Q~loCIGkaSGE8E literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/light.svg b/files/opencs/scalable/referenceable-record/light.svg index f8f506636..3bd5307f7 100644 --- a/files/opencs/scalable/referenceable-record/light.svg +++ b/files/opencs/scalable/referenceable-record/light.svg @@ -15,7 +15,7 @@ id="svg2" version="1.1" inkscape:version="0.48.4 r9939" - sodipodi:docname="light source.svg"> + sodipodi:docname="light.svg"> + transform="matrix(-0.90444509,0,0,0.90444509,-132.43957,95.466136)"> - diff --git a/files/opencs/scalable/referenceable-record/miscellaneous.png b/files/opencs/scalable/referenceable-record/miscellaneous.png new file mode 100644 index 0000000000000000000000000000000000000000..37862d3b54f114d16ece2cc31673c367f517cd2a GIT binary patch literal 1518 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 literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/random-item.png b/files/opencs/scalable/referenceable-record/random-item.png new file mode 100644 index 0000000000000000000000000000000000000000..9f1367a83da612c08e365f059b6f3e825d608eac GIT binary patch literal 1612 zcmZ`(X;4#F6uyB3Lc(4G1;dV!-LM20nj#=!sVv!)GFAwyM2aAUK?U+cKtXJ$RH;R@ zGc*Nhg^J?P4m49O6pB<3Dj+*$QG-$$kYxmfo{&yw`lDywyWctIeP_A%+<6z+ks&%H zGZI2bCoD9G3uvW$iR!Qh)s%Gt;ExAH1R!+hGxAnE0c>10HzW|<>ZQ&rnTes?2!zhk z5Rw!lv;i)O0-+o_LN5de`Boxil6k$A!$e3ei5<>o0Rco)Q`5}MOr`7S==k~hH8wW( z_xFRYast7|#wI*Gyt})5XJ;opJzYyn3qEOUYa1CERaI3jEiFw?PwVOFkw_#mnf&0v zgYE6@w6rwfSXfwK7&baOy1BWjudfdtS6A1`$;q6Y96FsoH8r)iwpLhJ=;r1Y5)!ho zurN0_2YI}_yt=x&-oAYs5dj-Q=H}*ESy`ai+S*>Za^>mMrzR#Q^YimtTU&;PhK`Po zB9Z9%^XF75RV)@m10Eh8EEcP?vy(!h;PH4LA0LH6VPIguWHPy2?)v)r;^LySvvYHE zb4yFh>gwvlhYx3FW+o;kyuH0=XJp{uL=v8E_n31MMj;2{tQDrazTus|Sy*+oS~shHr0sPXY}AVYGPwJJFdhl`Dkg`1!< z;aF4(tRPO2cs+n_5jT>D)E$$w4LF$?7DLdqJ6eEYVk({`5@T43WegY=sh}Ryh{MEj zP*^Exal0Uws$Hoo5 zhF#$j4uu4vQi6FX7+RU3G1+j+%9Gy2k#iZ>fG`#o6u|fSJyGC~f@vwn8sm~LKK-ib z^2I$R&U*VT?@6kwtIO#}ga#b9Q(6J~%ONrI8o9A!% zA5*6hzV@u`H%b*2b>xUvS9JWf588SXI%!t%JP)|7$dHRok z`COA#c=;~5OM_f3clwob@|8V_$%qt$FML_tL$m=WY{+ zGB-DBhbv;c@3*wKJS;dFTl(z0Z06D@+_5Hm;-B`7rGdQryciDUI`y13n?mP5`4<0V zhR2R>EQ-S=9<;5J(#}6K)=xcmGc|3||44b?NJn1*34gYlbUH6hLfY8aXD6B47g@zj z?&jZ?3VAoeuj=yYi7AQce0j^8h7k@Y`&sX`dxGgUmVi)a?D~-$U!nNYwf>lHxb70i z>BucL)0Pb*Y6EWU&d~S9l`}(o8>em?B+Sz)w^E2xCk~}6hSJA!tuBp5mTtMei>)ub zpSS*3$l4~Zd@I0by>Hq!HSFrN;yd1NqAje zyeQc>F)JAWxzpV|T<8oJcQ3x1x34=qo=$XkUpifW!9Mvv0qGe@!jv=rAJ8*UJ^}%z t$_l)U6j5$`Rx--X&2<%?Ov_G;&rEjB$U1)Q71InzD2x>ubSqFG{Tq|8Yfk_G literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/repair.png b/files/opencs/scalable/referenceable-record/repair.png new file mode 100644 index 0000000000000000000000000000000000000000..cb631d233766afdc6a058ea57a62d44378babfd4 GIT binary patch literal 1474 zcmZ`%dsNa_9RJzEvU0V`mQJ_MJk6T35T-ezLgb~18NOfT3$c8l1ez}d6af`5!9tLu zDVgRANkGx?m6j)8JzTBYX|399oqW}HPFl9>I%lW-vG4iZ@9TcQ=YAho%$Z5Y#SR|275&Y>QJAA{J^Lw|~A88Aqa!At?JB z2;vk%&?0bgrXh$0hoC>AAqb^_pwH8)Oh?fWw2JTV8;A!1L>~gthe#sfi9RbJc;j$H z9DzU}67hJF7XUDEL{BdQ28+jftq>ONiAH148QBaDKbKpS$1P$P2=fJEzDO#N%1UHs z%am$GT6#*&1+}2GAS5EVLRHqFtpm8!u4(SL*k)|fcWX_3hJkD5p^^TK>{FnOh+`qu z^-4{1wOA%%bF-7_iT(k8{y|4_IHy|;jj~D!otf<8L)^7%7bS>NSuNLfwX_-d8_l|eq<9PlV`pbaAQ93S$s$QnZDTbKhwd=8%N1uDnl!3v zMLaFm(4*BFn_}XRJ2^Q;MTZH*JayeUWsRIulp7Kr5PmE)G%^U(cACu!j|w9nJ)F); zIYJ?yq|<20)PxhUaS6v0lH%ChoI)Y5L?Q&7nUS8E&17Vz#wSK6rPI<_$;>P|Xbp)( zzW-+*Zy*RLfP>vEeZ+zJ0UtX*=>J}QtQgE%ovFFKtEs)SN!xj;%?QxgW@rSnYSlNi z=r48;=!Zx9FL$?e^t2j#+f4)d-eJ?wX#d#lk;$piopP}k(t*uI;ghy0gk! zxvKW8T60c$UM{H+6_*wAOE{dOoE&b3L@qM*8q9+xwMM}%%*y9y6^PhEX+cT3KqM_F zEY8<7)m$GRymfc{_T7oW5wpHW%N6AEgn3||r80q}qF7cb7L^qW#N5ul%gXZ=LJ3bS z7nWC+f{p-5=Ow*B$e0wr0Ep~IKJ4S|O(fuPURY1ep@X|O?n5FF2v=7)9GNvbfc^E= z!uy5 zItEiuFTeYxOxd#PQ4Z!3qN=J&B`@OTGE=jq^=-Nis>K@N!Oc7buJ+5e`Guc-yTiId zj6wQ99Yx{4Q)d4PlxGopn23XfFb5JatkOtf;MZD%4OuT)tj}~)fdHB}&NI;CMqKoE z2Iq{ZvXWmRRu{-hRDyHT;~0OTXDBYvHxf(n2`2>mu@|;(QlL^6OKp*~apeKpOeD+_ zzmsYcG&D8laK3MFOUYMPdh&8ZFr4Z`t(>)?FiWn7*SCpo+gCp+ z`_bAeYJ+9W<9iy%uj^{>Hb)uRgTwkSVq>2$UAJDP-|wNmFudHKF?0V4ZPxtGN;JK$ z+}**W^Y_Wejzp=$q4b42&ygdE3%h9(RSy_!7^$CMlCw9;TwYwi!{vY@(s{qrzP-IQ z+J;U|N3(tYt;v=?r-(4vs;N$!JCQJMxV?_WV*MEnv&IBFZiA7>#$2LdAu3hG1Fh{% zw#}y~ZNx1r+3dix>#4%rjj8n4yr)ZZeBAq~rY&=Vr&ql<*+H5&6OGN5n}fj~b~5py z%=j246&1&z0s$f5u1FWSn+w7{&~+aQ0pR8gN1)(vyJg3l|4B%p$Dc^Z`u~KaI#mit uuw8i}fS$n2jA2lr%*@O^CsLD6#l@si_s|(M)ePDW1VP?-KU^y|n)f%q0Dckx literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/static.png b/files/opencs/scalable/referenceable-record/static.png new file mode 100644 index 0000000000000000000000000000000000000000..934e8e2980b6bcc86d4292799c3df52f58ae156d GIT binary patch literal 1518 zcmZ{kdpHwn9LL{b%&gfmn#*=Haw@FNrRJ8#YI71JqIE$CxoxPmRZOwAO!6otBo*cK zOjeX+l)A{^qE%f53Tc`lY3XJBXpxQSiJ(%tTYM)qrT2w|eg0}#`w*x?s1Hi2I zOYjkZ{UiV;A^~te2f#9R+1(&d?LdFeW;#tvZE1Y(Woco^W^7N_M$aua#E9!!s*P** zqftY`+rMsmn)-r)`MKAV^Oh3833`L6zs7XE867+53*nRAce4CryqkdE6_{C7n;7PClL+D-E2N-R|f` z=(P5-i4npb#P)wwOL`?AaRB9v6&z7oofD}Bo6jh=+l=8YM=5n?W_MKc@@JFo3&Zg- z!ryCa8!bC1hd+5<9F@wQGPz zt_*7Mo!^Y$@i60z*SHn0)hm^XX58#hOJiauqBxj|y3L{LjZy@tZ}z6ix~rh*?DkWa zT}LU_1ee76JLOlbtqD5LzAUqx1bEh=QdfPX_u*5e+{pvfKb3?Yb`0ObB&?RLd7xWZ z2LV*jDrw8NY?_)dweZfIerY9;u=iAW<@w7PXF3b^e+p&Zu({T^wUH$!wr$Jv?K7Qq zL98^cXTiLTE61y5;hx4fpKo{;AMd?X%)-|nphIx_k3Hy4tg!xILwT@YmQ`}X>8kAx zKK%`KW8;PV3y_#3%YM0AmyCQrKs@|#Z(NjF9=5#XdE&^}2tjujfm2+}T=))6kt@!I zx>SVk);EBJhK0o%2mO)sQcd~3jL01AHZfme`ojcz6*<^4+5hlMi8Dp54l*EtgV>T1 zDpp8Q&&v%=I7!!{J4yUmmkCSDPjquK!GebE<~6ChS;)3cfq$*SZtZC}B*{r=>l%&x zkX939Sqw!BNe=b{cBQ#Y_@=cUn7R?w<5CPCPe03e$k8L;ijeNxaH0@xeh^P~7Mb@n zK+%=;EkkxV0_+8Ccn+XN=4nX?Cj9ZhF4~Y`J1|=AGc+zLJ3TjZ{dE&J(6%A4NW9%) zME&Y|NOM+%U8D2K{F*bSwNmMW8zIw;e$8Eu#I~~YmwH}Yy_uIC?r1PWrC>$*kW8Tl z$G5b@rR(^&y9+gWN)ZJn&4psZw%zqET#C_~?Jq0KIe!k7`?>EBj|yXACjdRLto852 zzGrI9*0+`K?MIILR|1=}CQqt1Cl5vm)kk=4l3T2w^SpOqtG^UK@=Bu1pFiJcj&+?ss|6r#0jTz0FO*d&!sCqIeVKyCF{v)h(O z(`DutM7Q0HPd%~=`K|J6%r9cL_fma`l5q~}vn{BIE+5Uz9lNcvcY6prDjHLA^M8XX zmZK_9!%DYE!zG9D4tnz}X}KFZ5__}+-M|`PjZO7NiN*#mJnJax7G3QBKyfpy8lL>R zKU8*4w!9I)o~DQINbEqQ?}NWzw&wd#0e)s>`AKQ9!sOATrUfN#eqX3<&&3L9uwhBJ z-e9%$Z%e{klab7tm~|f6;mIO1&Z#XE(~0u zP+Vc`7q=)Cn*3-?4UYb__f++&9r^mp10KnK0Bgi$$8j1#6)Gpx<{wQY5|-`WM@Z`tE1D}5b`>AC+%5lPjYf6k?hUf z{QqM}PK`;}%lm%=YjgHDt-*XTVQcE%3~p3fEZ}mv#DtW@^ynydEHO1Lu2ku1p%nqY MjRCY;pU9*C0-JS>N&o-= literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/referenceable-record/weapon.png b/files/opencs/scalable/referenceable-record/weapon.png new file mode 100644 index 0000000000000000000000000000000000000000..deb2e50bd181c1b12db3b31b666f96d84d7a36ca GIT binary patch literal 1465 zcmZ`&do+}37=K-66Or21rLnU#wVQ@n6yZ3cH8E?5L8aRogM@}4@kNb)diuLFA+*eM(8b= z5@r#KG(l+22O(l+*#?C9v|?(QBL z8M$-kjz}bW`0ybF0ZeIWsob8GmDSYL1TvS)t*EFN8ygb{1R%V4@#5*zr^(65IXOA~ z{rz2CT>zM#o^EMr!Q=5_vACzF$Ii|U@`AChu8zm!K?(>yH8ln9P#%Pxn3yOkDypok zoSU12$QcFMdSv$HS+8jS`>sO0^}9jqWEkx1k!$PgBi!fsYS-U0 zJd`1a!F-^Swzf983e8SVP6CzVtE;OaLVbO`T;*^$a8*`TCRbr)X=!P4xh}V=TeqU2 zg8v8MHus!mikA*QOgGJ2j~A*373O?rkRPBwK0aO?j88v>Pxad$dz8@G{ummRN~KT? z%nka2)bsQ6P!Dvyu&^*QGXq`2G#~{$=esBBf&I>;x_Y44uGCK`lSI?y*I47FwOLyo zf~LYAS^uHA`H@QF-LHnQ7J(fr>|HNMl$1=LJ+@qwC=1pnK9LNnG>6-%NwFaVA%V%A(ITu%O^CU9^FsVm2DaAw*!cC@fd}-NL&4ZQ zSxrOK-9dWoGu+RD=8?G7H+YI2%tc1gjoL8IhmW3*I9 zrrWUW7a-9%aA`iTxi0#L$t5)nZ7oUm72=3T;@Gw87woKfiR`#*PJ-KbeYcFA)T+B$ zZRPO2Z6E|9-gX0DmkqgF*e8yk7!;~z-m9r$C0w+A6KQawH%?h2MyPl{ZoQP4kA5mp znReycV1^HS7|1$>dD6WBzHei+oZ>AwR%aG%LL_GITeC5mJx!#(Zy2w)s;Hy - - - - - - - - - Date: Sun, 26 May 2013 17:31:29 +0200 Subject: [PATCH 059/213] Rastered status icons. ingredients, light, and book icon without emblem. --- files/opencs/raster/added.png | Bin 0 -> 1223 bytes files/opencs/raster/modified.png | Bin 0 -> 1855 bytes files/opencs/raster/removed.png | Bin 0 -> 1490 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 files/opencs/raster/added.png create mode 100644 files/opencs/raster/modified.png create mode 100644 files/opencs/raster/removed.png diff --git a/files/opencs/raster/added.png b/files/opencs/raster/added.png new file mode 100644 index 0000000000000000000000000000000000000000..456966a9c953555eb33677f2c6ad507b01b58529 GIT binary patch literal 1223 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D(<+r!7#%P+tuAjnTgR~zU^H8nLI9W7sfA6q+Xdq+DLS0^_Q7f&yD{{SB! zUr%KfB~ek)r%#_sNl7UxD|q{Q+Sppz+1q+~yDKRvNk~Zi|Nmc3PEJu#-rB|z=n;2M zS1%tAMJ1s1a+X%+);3o54t8?#axQL8<`!lSj`mJ2jzBNFx;s0$ILOJ%%F4<(Iy;z} znOIp{+SpnH!$DR~Mp{PN$k@=>#K^?d$jsct+``n#+QP!pOiD^pLQ-5`Ur$q0Lql8c)Q2qYxLWn`qZwY9{=#q{*_OiWC~CB)S=)cN`O)YMe@`1q8SmH7C0 z6%^!oczA#ob8~Y`OG|Nba*B$IaBy%434tPjg@r{xKtM=Hh@G9Cjg74;gmninj5tby z{DO7w|GoeB?|t0`H|1vn#Tb*k-CcBc-7Q=VvL>2>6&TkNA4N5OK$N4p$&#d4yc`JapLjb($+eiOJ6f?2P<3F(sRG(O#U?g z+mFI`KbGx%_x+vC^WA$Z?B+9HxR9|;Aos0oSoZR>_paW(o4UO;YJSO$I0Wq@uT64 zCzDl<`f^@AQ_W*%aQTpk`$W$=p(7&p%`P_%?KJ%H`&Yvb$-H|Q=cZyh-=xJQ&yWCe8=nQCkc_FmAZw+ z$+oj&o0DEv?~GZI^PJn>V8yjhx2HPo+!L&I=v|z`q#f^{Gyho1tJHXZ_lA0b9=|_} zGd?89^QkH;$R4`5QP9G!X>zb~K^0T_bGHY7c=T4eEvRBNy~%OHbVo=}LlI|q=wjEC z;S0PrEz&T0CAI$7uXi=((?SBST6u;3U%|yze=%^j@`BKMo>#wq)HDBhXv3y!HR0ps z$)y*V)b4tn>J__n-dQcf^kMyrm-lB!j}VJsDux!5|5;Aviy+ pq&%@Gm7%=6TrV>(yEr+qAXP8FD1G)j8!4b722WQ%mvv4FO#p%Rp2PqE literal 0 HcmV?d00001 diff --git a/files/opencs/raster/modified.png b/files/opencs/raster/modified.png new file mode 100644 index 0000000000000000000000000000000000000000..ca613f9e48f89cd597f9a1296a7b6cd921cb19eb GIT binary patch literal 1855 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 II;Vst04OK`B>(^b literal 0 HcmV?d00001 From e37324b967aa99406ebfed37c33585c5d169de05 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Sun, 26 May 2013 08:49:44 -0700 Subject: [PATCH 060/213] AIWander everything works. only two things to do: Implement limiting selection on z axis, and correcting decision algorithm. --- apps/openmw/mwmechanics/aiwander.cpp | 297 ++++++++++++++++++++++++++- apps/openmw/mwmechanics/aiwander.hpp | 35 ++++ 2 files changed, 330 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index a73047548..52ab34f24 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -1,9 +1,54 @@ #include "aiwander.hpp" #include +#include "movement.hpp" + +#include "../mwworld/class.hpp" +#include "../mwworld/player.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" + +#include + +namespace +{ + float sgn(float a) + { + if(a > 0) return 1.0; + else return -1.0; + } +} + MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat): mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat) { + std::cout << "AIWander: " << mDistance << " " << mDuration << " " << mTimeOfDay << " "; + for(unsigned short counter = 0; counter < mIdle.size(); counter++) + { + std::cout << mIdle[counter] << " "; + if(mIdle[counter] >= 127 || mIdle[counter] < 0) + mIdle[counter] = 0; + } + std::cout << mRepeat << std::endl; + + if(mDistance < 0) + mDistance = 0; + if(mDuration < 0) + mDuration = 0; + if(mDuration == 0) + mTimeOfDay = 0; + + srand(time(NULL)); + mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mChanceMultiplyer = 0.75; + mPlayedIdle = 0; + + mStoredAvailableNodes = false; + mChooseAction = true; + mIdleNow = false; + mMoveNow = false; + mWalking = false; } MWMechanics::AiPackage * MWMechanics::AiWander::clone() const @@ -13,11 +58,259 @@ MWMechanics::AiPackage * MWMechanics::AiWander::clone() const bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) { - // Return completed - return true; + if(mDuration) + { + // End package if duration is complete or mid-night hits: + MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + if(currentTime.getHour() >= mStartTime.getHour() + mDuration) + { + if(!mRepeat) + { + stopWalking(actor, mPathFinder); + return true; + } + else + mStartTime = currentTime; + } + else if(int(currentTime.getHour()) == 0 && currentTime.getDay() != mStartTime.getDay()) + { + stopWalking(actor, mPathFinder); + + if(!mRepeat) + { + stopWalking(actor, mPathFinder); + return true; + } + else + mStartTime = currentTime; + } + } + + ESM::Position pos = actor.getRefData().getPosition(); + + if(!mStoredAvailableNodes) + { + mStoredAvailableNodes = true; + mPathgrid = + MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); + + mCellX = actor.getCell()->mCell->mData.mX; + mCellY = actor.getCell()->mCell->mData.mY; + + if(mDistance != 0 && !mPathgrid->mPoints.empty()) + { + // TODO: Limit selecting range in the Z axis. + mXCell = 0; + mYCell = 0; + if(actor.getCell()->mCell->isExterior()) + { + mXCell = mCellX * ESM::Land::REAL_SIZE; + mYCell = mCellY * ESM::Land::REAL_SIZE; + } + + Ogre::Vector3 npcPos(actor.getRefData().getPosition().pos); + npcPos[0] = npcPos[0] - mXCell; + npcPos[1] = npcPos[1] - mYCell; + + for(unsigned int counter = 0; counter < mPathgrid->mPoints.size(); counter++) + { + Ogre::Vector3 nodePos(mPathgrid->mPoints[counter].mX, mPathgrid->mPoints[counter].mY, mPathgrid->mPoints[counter].mZ); + if(npcPos.squaredDistance(nodePos) <= mDistance * mDistance) + mAllowedNodes.push_back(mPathgrid->mPoints[counter]); + } + if(!mAllowedNodes.empty()) + { + Ogre::Vector3 firstNodePos(mAllowedNodes[0].mX, mAllowedNodes[0].mY, mAllowedNodes[0].mZ); + float closestNode = npcPos.squaredDistance(firstNodePos); + unsigned int index = 0; + for(unsigned int counterThree = 1; counterThree < mAllowedNodes.size(); counterThree++) + { + Ogre::Vector3 nodePos(mAllowedNodes[counterThree].mX, mAllowedNodes[counterThree].mY, mAllowedNodes[counterThree].mZ); + float tempDist = npcPos.squaredDistance(nodePos); + if(tempDist < closestNode) + index = counterThree; + } + mCurrentNode = mAllowedNodes[index]; + mAllowedNodes.erase(mAllowedNodes.begin() + index); + } + } + } + + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + bool cellChange = actor.getCell()->mCell->mData.mX != mCellX || actor.getCell()->mCell->mData.mY != mCellY; + + if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) + { + int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); + // Check if actor is near the border of an inactive cell. If so, disable AiWander. + // FIXME: This *should* pause the AiWander package instead of terminating it. + if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / 2.0 - 200)) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } + } + + if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) + { + int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); + // Check if actor is near the border of an inactive cell. If so, disable AiWander. + // FIXME: This *should* pause the AiWander package instead of terminating it. + if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / 2.0 - 200)) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } + } + + // Don't try to move if you are in a new cell (ie: positioncell command called) but still play idles. + if(cellChange || (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY)) + mDistance = 0; + + if(mChooseAction) + { + mPlayedIdle = 0; + unsigned short idleRoll = 0; + + for(unsigned int counter = 1; counter < mIdle.size(); counter++) + { + unsigned short idleChance = mChanceMultiplyer * mIdle[counter]; + unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mChanceMultiplyer)); + if(randSelect < idleChance && randSelect > idleRoll) + { + mPlayedIdle = counter; + idleRoll = randSelect; + } + } + + if(!mPlayedIdle && mDistance) + { + std::cout << "Walking!" << std::endl; + mChooseAction = false; + mMoveNow = true; + } + else + { + // Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander: + std::cout << "Idling!" << std::endl; + MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mStartTime = currentTime; + playIdle(actor, mPlayedIdle + 1); + mChooseAction = false; + mIdleNow = true; + } + } + + if(mIdleNow) + { + // TODO: This is where we should be checking to see if the current idle animation is done, if it is then + // set mChooseAction to true, because there is no function for this yet we will only set mChooseAction to true. + if(!checkIdle(actor, mPlayedIdle + 1)) + { + std::cout << "Idle Really Completed" << std::endl; + mPlayedIdle = 0; + mIdleNow = false; + mChooseAction = true; + } + } + + if(mMoveNow == true && (mDistance != 0 && !mAllowedNodes.empty())) + { + if(!mPathFinder.isPathConstructed()) + { + unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size()); + Ogre::Vector3 destNodePos(mAllowedNodes[randNode].mX, mAllowedNodes[randNode].mY, mAllowedNodes[randNode].mZ); + + // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): + ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; + mAllowedNodes.erase(mAllowedNodes.begin() + randNode); + mAllowedNodes.push_back(mCurrentNode); + mCurrentNode = temp; + + ESM::Pathgrid::Point dest; + dest.mX = destNodePos[0] + mXCell; + dest.mY = destNodePos[1] + mYCell; + dest.mZ = destNodePos[2]; + + ESM::Pathgrid::Point start; + start.mX = pos.pos[0]; + start.mY = pos.pos[1]; + start.mZ = pos.pos[2]; + + mPathFinder.buildPath(start,dest,mPathgrid,mXCell,mYCell); + mWalking = true; + } + } + + if(mWalking) + { + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); + MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + } + + if(mWalking && mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) + { + stopWalking(actor, mPathFinder); + mMoveNow = false; + mWalking = false; + mChooseAction = true; + } + + return false; } int MWMechanics::AiWander::getTypeId() const { return 0; } + +void MWMechanics::AiWander::stopWalking(const MWWorld::Ptr& actor, PathFinder& path) +{ + PathFinder pathClearer; + path = pathClearer; + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; +} + +void MWMechanics::AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) +{ + if(idleSelect == 2) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle2", 0, 1); + else if(idleSelect == 3) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); + else if(idleSelect == 4) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle4", 0, 1); + else if(idleSelect == 5) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle5", 0, 1); + else if(idleSelect == 6) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle6", 0, 1); + else if(idleSelect == 7) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle7", 0, 1); + else if(idleSelect == 8) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle8", 0, 1); + else if(idleSelect == 9) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle9", 0, 1); +} + +bool MWMechanics::AiWander::checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) +{ + if(idleSelect == 2) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle2"); + else if(idleSelect == 3) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle3"); + else if(idleSelect == 4) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle4"); + else if(idleSelect == 5) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle5"); + else if(idleSelect == 6) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle6"); + else if(idleSelect == 7) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle7"); + else if(idleSelect == 8) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle8"); + else if(idleSelect == 9) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle9"); + else + return false; +} + diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index e06e714bc..0a00059cc 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -4,6 +4,10 @@ #include "aipackage.hpp" #include +#include "pathfinding.hpp" + +#include "../mwworld/timestamp.hpp" + namespace MWMechanics { class AiWander : public AiPackage @@ -18,11 +22,42 @@ namespace MWMechanics ///< 0: Wander private: + void stopWalking(const MWWorld::Ptr& actor, PathFinder& path); + void playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); + bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); + int mDistance; int mDuration; int mTimeOfDay; std::vector mIdle; bool mRepeat; + + float mX; + float mY; + float mZ; + + int mCellX; + int mCellY; + float mXCell; + float mYCell; + + bool mStoredAvailableNodes; + bool mChooseAction; + bool mIdleNow; + bool mMoveNow; + bool mWalking; + + float mChanceMultiplyer; + unsigned short mPlayedIdle; + + MWWorld::TimeStamp mStartTime; + + std::vector mAllowedNodes; + ESM::Pathgrid::Point mCurrentNode; + + PathFinder mPathFinder; + const ESM::Pathgrid *mPathgrid; + }; } From 96daad7a226e0fe83bd2e9c92e3c752c283a5286 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Sun, 26 May 2013 09:31:56 -0700 Subject: [PATCH 061/213] AIWander - shortened some if statements and made super minor optimizations to others, now using proper GMST to load proper idlechance instead of hacky set value." --- apps/openmw/mwmechanics/aiwander.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 52ab34f24..fd96071cc 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -41,8 +41,9 @@ MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const srand(time(NULL)); mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp(); - mChanceMultiplyer = 0.75; mPlayedIdle = 0; + mChanceMultiplyer = + MWBase::Environment::get().getWorld()->getStore().get().find("fIdleChanceMultiplier")->getFloat(); mStoredAvailableNodes = false; mChooseAction = true; @@ -74,8 +75,6 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) } else if(int(currentTime.getHour()) == 0 && currentTime.getDay() != mStartTime.getDay()) { - stopWalking(actor, mPathFinder); - if(!mRepeat) { stopWalking(actor, mPathFinder); @@ -97,7 +96,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) mCellX = actor.getCell()->mCell->mData.mX; mCellY = actor.getCell()->mCell->mData.mY; - if(mDistance != 0 && !mPathgrid->mPoints.empty()) + if(mDistance && !mPathgrid->mPoints.empty()) { // TODO: Limit selecting range in the Z axis. mXCell = 0; @@ -164,7 +163,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) } // Don't try to move if you are in a new cell (ie: positioncell command called) but still play idles. - if(cellChange || (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY)) + if(mDistance && (cellChange || (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY))) mDistance = 0; if(mChooseAction) @@ -185,14 +184,12 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) if(!mPlayedIdle && mDistance) { - std::cout << "Walking!" << std::endl; mChooseAction = false; mMoveNow = true; } else { // Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander: - std::cout << "Idling!" << std::endl; MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); mStartTime = currentTime; playIdle(actor, mPlayedIdle + 1); @@ -203,18 +200,15 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) if(mIdleNow) { - // TODO: This is where we should be checking to see if the current idle animation is done, if it is then - // set mChooseAction to true, because there is no function for this yet we will only set mChooseAction to true. if(!checkIdle(actor, mPlayedIdle + 1)) { - std::cout << "Idle Really Completed" << std::endl; mPlayedIdle = 0; mIdleNow = false; mChooseAction = true; } } - if(mMoveNow == true && (mDistance != 0 && !mAllowedNodes.empty())) + if(mMoveNow && mDistance && !mAllowedNodes.empty()) { if(!mPathFinder.isPathConstructed()) { From fd96d47fe4ab81af86d8dc89b39b399f9d6bf014 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Sun, 26 May 2013 11:30:42 -0700 Subject: [PATCH 062/213] AIWander Completed. Replicates vanilla as best possible, pathfinding needs fixing before this looks correct but once the pathfinding files are edited this will behave pretty much exactly as vanilla. Major credit to Hrnchamd for major research. --- apps/openmw/mwmechanics/aiwander.cpp | 34 ++++++++++++++++------------ apps/openmw/mwmechanics/aiwander.hpp | 2 +- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index fd96071cc..67f9cc112 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -1,5 +1,4 @@ #include "aiwander.hpp" -#include #include "movement.hpp" @@ -23,14 +22,11 @@ namespace MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat): mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat) { - std::cout << "AIWander: " << mDistance << " " << mDuration << " " << mTimeOfDay << " "; for(unsigned short counter = 0; counter < mIdle.size(); counter++) { - std::cout << mIdle[counter] << " "; if(mIdle[counter] >= 127 || mIdle[counter] < 0) mIdle[counter] = 0; } - std::cout << mRepeat << std::endl; if(mDistance < 0) mDistance = 0; @@ -42,7 +38,7 @@ MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const srand(time(NULL)); mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp(); mPlayedIdle = 0; - mChanceMultiplyer = + mIdleChanceMultiplier = MWBase::Environment::get().getWorld()->getStore().get().find("fIdleChanceMultiplier")->getFloat(); mStoredAvailableNodes = false; @@ -98,7 +94,6 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) if(mDistance && !mPathgrid->mPoints.empty()) { - // TODO: Limit selecting range in the Z axis. mXCell = 0; mYCell = 0; if(actor.getCell()->mCell->isExterior()) @@ -173,8 +168,8 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) for(unsigned int counter = 1; counter < mIdle.size(); counter++) { - unsigned short idleChance = mChanceMultiplyer * mIdle[counter]; - unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mChanceMultiplyer)); + unsigned short idleChance = mIdleChanceMultiplier * mIdle[counter]; + unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mIdleChanceMultiplier)); if(randSelect < idleChance && randSelect > idleRoll) { mPlayedIdle = counter; @@ -241,14 +236,23 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; - } - if(mWalking && mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) - { - stopWalking(actor, mPathFinder); - mMoveNow = false; - mWalking = false; - mChooseAction = true; + // Unclog path nodes by allowing the NPC to be a small distance away from the center. This way two NPCs can be + // at the same path node at the same time and both will complete instead of endlessly walking into eachother: + Ogre::Vector3 destNodePos(mCurrentNode.mX, mCurrentNode.mY, mCurrentNode.mZ); + Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos); + actorPos[0] = actorPos[0] - mXCell; + actorPos[1] = actorPos[1] - mYCell; + float distance = actorPos.squaredDistance(destNodePos); + + if(distance < 1200 || mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) + { + stopWalking(actor, mPathFinder); + mMoveNow = false; + mWalking = false; + mChooseAction = true; + } + } return false; diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index 0a00059cc..cf3820527 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -47,7 +47,7 @@ namespace MWMechanics bool mMoveNow; bool mWalking; - float mChanceMultiplyer; + float mIdleChanceMultiplier; unsigned short mPlayedIdle; MWWorld::TimeStamp mStartTime; From 3a6e54c4f515d1643506a5a672f4bd76c6b786e6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 27 May 2013 02:18:36 +0200 Subject: [PATCH 063/213] Sell owned items in the cell --- apps/openmw/mwbase/world.hpp | 2 + apps/openmw/mwgui/containeritemmodel.cpp | 71 +++++++++++++++++++++-- apps/openmw/mwgui/containeritemmodel.hpp | 3 +- apps/openmw/mwgui/itemmodel.cpp | 34 +++++++++-- apps/openmw/mwgui/sortfilteritemmodel.cpp | 2 +- apps/openmw/mwgui/tradewindow.cpp | 4 +- apps/openmw/mwworld/worldimp.cpp | 27 +++++++++ apps/openmw/mwworld/worldimp.hpp | 2 + 8 files changed, 131 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index de1a34792..86a6a89d2 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -342,6 +342,8 @@ namespace MWBase virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector& out) = 0; ///< get all containers in active cells owned by this Npc + virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector& out) = 0; + ///< get all items in active cells owned by this Npc virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index 79351c6ca..5d23744b2 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -3,11 +3,39 @@ #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" + +namespace +{ + + bool stacks (const MWWorld::Ptr& left, const MWWorld::Ptr& right) + { + if (left == right) + return true; + + // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure + if (left.getContainerStore() && right.getContainerStore()) + return left.getContainerStore()->stacks(left, right) + && right.getContainerStore()->stacks(left, right); + + if (left.getContainerStore()) + return left.getContainerStore()->stacks(left, right); + if (right.getContainerStore()) + return right.getContainerStore()->stacks(left, right); + + MWWorld::ContainerStore store; + return store.stacks(left, right); + } + +} + namespace MWGui { -ContainerItemModel::ContainerItemModel(const std::vector& itemSources) +ContainerItemModel::ContainerItemModel(const std::vector& itemSources, const std::vector& worldItems) : mItemSources(itemSources) + , mWorldItems(worldItems) { assert (mItemSources.size()); } @@ -65,8 +93,7 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { - // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure - if (*it == item.mBase || (store.stacks(*it, item.mBase) && item.mBase.getContainerStore()->stacks(*it, item.mBase))) + if (stacks(*it, item.mBase)) { int refCount = it->getRefData().getCount(); it->getRefData().setCount(std::max(0, refCount - toRemove)); @@ -76,6 +103,21 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count) } } } + for (std::vector::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source) + { + if (stacks(*source, item.mBase)) + { + int refCount = source->getRefData().getCount(); + if (refCount - toRemove <= 0) + MWBase::Environment::get().getWorld()->deleteObject(*source); + else + source->getRefData().setCount(std::max(0, refCount - toRemove)); + toRemove -= refCount; + if (toRemove <= 0) + return; + } + } + throw std::runtime_error("Not enough items to remove could be found"); } @@ -91,8 +133,7 @@ void ContainerItemModel::update() std::vector::iterator itemStack = mItems.begin(); for (; itemStack != mItems.end(); ++itemStack) { - // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure - if (store.stacks(itemStack->mBase, *it) && it->getContainerStore()->stacks(itemStack->mBase, *it)) + if (stacks(*it, itemStack->mBase)) { // we already have an item stack of this kind, add to it itemStack->mCount += it->getRefData().getCount(); @@ -108,6 +149,26 @@ void ContainerItemModel::update() } } } + for (std::vector::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source) + { + std::vector::iterator itemStack = mItems.begin(); + for (; itemStack != mItems.end(); ++itemStack) + { + if (stacks(*source, itemStack->mBase)) + { + // we already have an item stack of this kind, add to it + itemStack->mCount += source->getRefData().getCount(); + break; + } + } + + if (itemStack == mItems.end()) + { + // no stack yet, create one + ItemStack newItem (*source, this, source->getRefData().getCount()); + mItems.push_back(newItem); + } + } } } diff --git a/apps/openmw/mwgui/containeritemmodel.hpp b/apps/openmw/mwgui/containeritemmodel.hpp index 2f4c708ba..22595582e 100644 --- a/apps/openmw/mwgui/containeritemmodel.hpp +++ b/apps/openmw/mwgui/containeritemmodel.hpp @@ -11,7 +11,7 @@ namespace MWGui class ContainerItemModel : public ItemModel { public: - ContainerItemModel (const std::vector& itemSources); + ContainerItemModel (const std::vector& itemSources, const std::vector& worldItems); ///< @note The order of elements \a itemSources matters here. The first element has the highest priority for removal, /// while the last element will be used to add new items to. @@ -28,6 +28,7 @@ namespace MWGui private: std::vector mItemSources; + std::vector mWorldItems; std::vector mItems; }; diff --git a/apps/openmw/mwgui/itemmodel.cpp b/apps/openmw/mwgui/itemmodel.cpp index 0dc2bb62c..58e89c4fc 100644 --- a/apps/openmw/mwgui/itemmodel.cpp +++ b/apps/openmw/mwgui/itemmodel.cpp @@ -13,8 +13,6 @@ namespace MWGui , mType(Type_Normal) , mBase(base) { - assert(base.getContainerStore()); - if (MWWorld::Class::get(base).getEnchantment(base) != "") mFlags |= Flag_Enchanted; } @@ -31,18 +29,42 @@ namespace MWGui { if(mBase == other.mBase) return true; - return mBase.getContainerStore()->stacks(mBase, other.mBase) - && other.mBase.getContainerStore()->stacks(mBase, other.mBase); + + // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure + if (mBase.getContainerStore() && other.mBase.getContainerStore()) + return mBase.getContainerStore()->stacks(mBase, other.mBase) + && other.mBase.getContainerStore()->stacks(mBase, other.mBase); + + if (mBase.getContainerStore()) + return mBase.getContainerStore()->stacks(mBase, other.mBase); + if (other.mBase.getContainerStore()) + return other.mBase.getContainerStore()->stacks(mBase, other.mBase); + + MWWorld::ContainerStore store; + return store.stacks(mBase, other.mBase); + } bool operator == (const ItemStack& left, const ItemStack& right) { if (left.mType != right.mType) return false; + if(left.mBase == right.mBase) return true; - return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase) - && right.mBase.getContainerStore()->stacks(left.mBase, right.mBase); + + // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure + if (left.mBase.getContainerStore() && right.mBase.getContainerStore()) + return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase) + && right.mBase.getContainerStore()->stacks(left.mBase, right.mBase); + + if (left.mBase.getContainerStore()) + return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase); + if (right.mBase.getContainerStore()) + return right.mBase.getContainerStore()->stacks(left.mBase, right.mBase); + + MWWorld::ContainerStore store; + return store.stacks(left.mBase, right.mBase); } ItemModel::ItemModel() diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index 60cc2fb0e..b88ec7c0b 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -71,7 +71,7 @@ namespace MWGui if (item.mType == ItemStack::Type_Equipped && !mShowEquipped) return false; - int category; + int category = 0; if (base.getTypeName() == typeid(ESM::Armor).name() || base.getTypeName() == typeid(ESM::Clothing).name()) category = Category_Apparel; diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 6a46478af..01f7e2419 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -88,8 +88,10 @@ namespace MWGui MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources); // Important: actor goes last, so that items purchased by the merchant go into his inventory itemSources.push_back(actor); + std::vector worldItems; + MWBase::Environment::get().getWorld()->getItemsOwnedBy(actor, worldItems); - mTradeModel = new TradeItemModel(new ContainerItemModel(itemSources), mPtr); + mTradeModel = new TradeItemModel(new ContainerItemModel(itemSources, worldItems), mPtr); mSortModel = new SortFilterItemModel(mTradeModel); mItemView->setModel (mSortModel); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8b76efdae..16cba2ea8 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1724,4 +1724,31 @@ namespace MWWorld } } } + + struct ListHandlesFunctor + { + std::vector mHandles; + + bool operator() (ESM::CellRef& ref, RefData& data) + { + Ogre::SceneNode* handle = data.getBaseNode(); + if (handle) + mHandles.push_back(handle->getName()); + return true; + } + }; + + void World::getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector& out) + { + const Scene::CellStoreCollection& collection = mWorldScene->getActiveCells(); + for (Scene::CellStoreCollection::const_iterator cellIt = collection.begin(); cellIt != collection.end(); ++cellIt) + { + ListHandlesFunctor functor; + (*cellIt)->forEach(functor); + + for (std::vector::iterator it = functor.mHandles.begin(); it != functor.mHandles.end(); ++it) + if (Misc::StringUtils::ciEqual(searchPtrViaHandle(*it).mCellRef->mOwner, npc.getCellRef().mRefID)) + out.push_back(searchPtrViaHandle(*it)); + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 1baf3d4ba..12438efd4 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -391,6 +391,8 @@ namespace MWWorld virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector& out); ///< get all containers in active cells owned by this Npc + virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector& out); + ///< get all items in active cells owned by this Npc virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); From feb180724cb5a94ad856d1a2c8f0b71947cf0d8b Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Sun, 26 May 2013 19:33:45 -0700 Subject: [PATCH 064/213] AI Execution Fix - Preiovusly AiExecute was being called even when in a menu, this was not correct behavior. --- apps/openmw/mwmechanics/actors.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 00f2ac6fe..37bba6d3a 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -30,7 +30,8 @@ namespace MWMechanics // AI CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); - creatureStats.getAiSequence().execute (ptr); + if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) + creatureStats.getAiSequence().execute (ptr); } void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) From 3b43ee751e2999d9599b476f0367507eed5079eb Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Sun, 26 May 2013 19:54:59 -0700 Subject: [PATCH 065/213] AI Execute Fix - May as well not create the object either to save extra time. --- apps/openmw/mwmechanics/actors.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 37bba6d3a..e85aa9b83 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -29,9 +29,11 @@ namespace MWMechanics calculateCreatureStatModifiers (ptr); // AI - CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); creatureStats.getAiSequence().execute (ptr); + } } void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) From bd6d54cc8fdeafeaaa4328484aa978ef17f2d41b Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Mon, 27 May 2013 03:24:41 -0700 Subject: [PATCH 066/213] AIWander Minor Patch - Forgot an else statement and another check on an empty node vector, previously no nodes in range or only one would cause the AIWander to not do anything, now they will play idles correctly still. --- apps/openmw/mwmechanics/aiwander.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 67f9cc112..4f7b69016 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -126,7 +126,11 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) } mCurrentNode = mAllowedNodes[index]; mAllowedNodes.erase(mAllowedNodes.begin() + index); + if(mAllowedNodes.empty()) + mDistance = 0; } + else + mDistance = 0; } } @@ -203,7 +207,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) } } - if(mMoveNow && mDistance && !mAllowedNodes.empty()) + if(mMoveNow && mDistance) { if(!mPathFinder.isPathConstructed()) { From 56edc1b2139bbcf152c0a8285b92352f923d3c93 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 12:26:06 +0200 Subject: [PATCH 067/213] Correction of getting spell range "Target". --- apps/openmw/mwmechanics/enchanting.cpp | 2 +- apps/openmw/mwmechanics/enchanting.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index ded75f03a..e53a14120 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -160,7 +160,7 @@ namespace MWMechanics cost1 *= constDurationMultipler; cost2 *= 2; } - if(effect->mData.mFlags & ESM::MagicEffect::CastTarget) + if(it->mRange == ESM::RT_Target) cost1 *= 1.5; float fullcost = cost1+cost2; diff --git a/apps/openmw/mwmechanics/enchanting.hpp b/apps/openmw/mwmechanics/enchanting.hpp index 2831f9ddb..d7acf60e7 100644 --- a/apps/openmw/mwmechanics/enchanting.hpp +++ b/apps/openmw/mwmechanics/enchanting.hpp @@ -3,6 +3,7 @@ #include #include "../mwworld/ptr.hpp" #include +#include #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" namespace MWMechanics From 4788b5e2261c6ab0d1b8a63f1d3a6d70c6f87f7b Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 14:42:08 +0200 Subject: [PATCH 068/213] Better formula for enchantment cost and code refactorization. --- apps/openmw/mwgui/enchantingdialog.cpp | 6 +- apps/openmw/mwmechanics/enchanting.cpp | 97 +++++++++++++++----------- apps/openmw/mwmechanics/enchanting.hpp | 6 +- components/esm/defs.hpp | 9 +++ 4 files changed, 73 insertions(+), 45 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 799a89ab5..3672c2aec 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -70,7 +70,7 @@ namespace MWGui mPrice->setCaption(boost::lexical_cast(mEnchanting.getEnchantPrice())); - switch(mEnchanting.getEnchantType()) + switch(mEnchanting.getCastStyle()) { case 0: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce","Cast Once")); @@ -169,7 +169,7 @@ namespace MWGui image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem); mEnchanting.setOldItem(item); - mEnchanting.nextEnchantType(); + mEnchanting.nextCastStyle(); updateLabels(); } @@ -248,7 +248,7 @@ namespace MWGui void EnchantingDialog::onTypeButtonClicked(MyGUI::Widget* sender) { - mEnchanting.nextEnchantType(); + mEnchanting.nextCastStyle(); updateLabels(); } diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index e53a14120..8efbf3c8c 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -12,7 +12,7 @@ namespace MWMechanics { Enchanting::Enchanting(): - mEnchantType(0) + mCastStyle(ESM::CS_CastOnce) {} void Enchanting::setOldItem(MWWorld::Ptr oldItem) @@ -41,9 +41,9 @@ namespace MWMechanics mEffectList=effectList; } - int Enchanting::getEnchantType() const + int Enchanting::getCastStyle() const { - return mEnchantType; + return mCastStyle; } void Enchanting::setSoulGem(MWWorld::Ptr soulGem) @@ -74,11 +74,11 @@ namespace MWMechanics MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1); } - if(mEnchantType==3) + if(mCastStyle==3) { enchantment.mData.mCharge=0; } - enchantment.mData.mType = mEnchantType; + enchantment.mData.mType = mCastStyle; enchantment.mData.mCost = getEnchantCost(); enchantment.mEffects = mEffectList; @@ -98,78 +98,97 @@ namespace MWMechanics return true; } - void Enchanting::nextEnchantType() + void Enchanting::nextCastStyle() { - mEnchantType++; + mCastStyle++; if (itemEmpty()) { - mEnchantType = 0; + mCastStyle = 0; return; } if ((mObjectType == typeid(ESM::Armor).name())||(mObjectType == typeid(ESM::Clothing).name())) { int soulConstAmount = MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->getInt(); - switch(mEnchantType) + switch(mCastStyle) { case 1: - mEnchantType = 2; + mCastStyle = 2; case 3: if(getGemCharge() 2 or (2 + 0) == (1 + 2) => 3 + * + * Formula on UESPWiki is not entirely correct. + */ float Enchanting::getEnchantCost() const { + if (mEffectList.mList.empty()) + // No effects added, cost = 0 + return 0; + const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - float cost = 0; std::vector mEffects = mEffectList.mList; - int i=mEffects.size(); - if(i<=0) - return 0; - /* - Formula from http://www.uesp.net/wiki/Morrowind:Enchant - */ + float enchantmentCost = 0; + int effectsLeftCnt = mEffects.size(); + float baseCost, magnitudeCost, areaCost; + int magMin, magMax, area; for (std::vector::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it) { - const ESM::MagicEffect* effect = store.get().find(it->mEffectID); + baseCost = (store.get().find(it->mEffectID))->mData.mBaseCost; + // To reflect vanilla behavior + magMin = (it->mMagnMin == 0) ? 1 : it->mMagnMin; + magMax = (it->mMagnMax == 0) ? 1 : it->mMagnMax; + area = (it->mArea == 0) ? 1 : it->mArea; - float cost1 = ((it->mMagnMin + it->mMagnMax)*it->mDuration*effect->mData.mBaseCost*0.025); - - float cost2 = (std::max(1, it->mArea)*0.125*effect->mData.mBaseCost); - - if(mEnchantType==3) + if (mCastStyle == ESM::CS_ConstantEffect) { - int constDurationMultipler = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentConstantDurationMult")->getFloat(); - cost1 *= constDurationMultipler; - cost2 *= 2; + magnitudeCost = (magMin + magMax) * baseCost * 2.5; + } + else + { + magnitudeCost = (magMin + magMax) * it->mDuration * baseCost * 0.025; + if(it->mRange == ESM::RT_Target) + magnitudeCost *= 1.5; } - if(it->mRange == ESM::RT_Target) - cost1 *= 1.5; - float fullcost = cost1+cost2; - fullcost*= i; - i--; + areaCost = area * 0.025 * baseCost; + if (it->mRange == ESM::RT_Target) + areaCost *= 1.5; - cost+=fullcost; + enchantmentCost += (magnitudeCost + areaCost) * effectsLeftCnt; + --effectsLeftCnt; } - return cost; + + return enchantmentCost; } int Enchanting::getEnchantPrice() const @@ -236,7 +255,7 @@ namespace MWMechanics + (0.125 * creatureStats.getAttribute (ESM::Attribute::Luck).getModified())); float chance2 = 2.5 * getEnchantCost(); - if(mEnchantType==3) + if(mCastStyle==3) { float constantChance = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentConstantChanceMult")->getFloat(); chance2 /= constantChance; diff --git a/apps/openmw/mwmechanics/enchanting.hpp b/apps/openmw/mwmechanics/enchanting.hpp index d7acf60e7..a04bd86e9 100644 --- a/apps/openmw/mwmechanics/enchanting.hpp +++ b/apps/openmw/mwmechanics/enchanting.hpp @@ -14,7 +14,7 @@ namespace MWMechanics MWWorld::Ptr mSoulGemPtr; MWWorld::Ptr mEnchanter; - int mEnchantType; + int mCastStyle; bool mSelfEnchanting; @@ -34,8 +34,8 @@ namespace MWMechanics void setEffect(ESM::EffectList effectList); void setSoulGem(MWWorld::Ptr soulGem); bool create(); //Return true if created, false if failed. - void nextEnchantType(); //Set enchant type to next possible type (for mOldItemPtr object) - int getEnchantType() const; + void nextCastStyle(); //Set enchant type to next possible type (for mOldItemPtr object) + int getCastStyle() const; float getEnchantCost() const; int getEnchantPrice() const; float getMaxEnchantValue() const; diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index bd86f9ba0..f47463891 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -23,6 +23,15 @@ enum RangeType RT_Target = 2 }; +// Casting style (in enchanting) +enum Type +{ + CS_CastOnce = 0, + CS_WhenStrikes = 1, + CS_WhenUsed = 2, + CS_ConstantEffect = 3 +}; + #pragma pack(push) #pragma pack(1) From cfbdf3f7797427e2bf9004ef05209adc06e05a0e Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 15:37:31 +0200 Subject: [PATCH 069/213] Enum Type renamed to CastingStyle --- components/esm/defs.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index f47463891..7586413a6 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -24,7 +24,7 @@ enum RangeType }; // Casting style (in enchanting) -enum Type +enum CastingStyle { CS_CastOnce = 0, CS_WhenStrikes = 1, From 252a1d92231777ddf66247caba69a4abe62e59f8 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 15:50:47 +0200 Subject: [PATCH 070/213] Replacement of some magical constants --- apps/openmw/mwgui/enchantingdialog.cpp | 8 ++++---- apps/openmw/mwmechanics/enchanting.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 3672c2aec..86bdc25fc 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -72,19 +72,19 @@ namespace MWGui switch(mEnchanting.getCastStyle()) { - case 0: + case ESM::CS_CastOnce: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce","Cast Once")); mAddEffectDialog.constantEffect=false; break; - case 1: + case ESM::CS_WhenStrikes: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenStrikes", "When Strikes")); mAddEffectDialog.constantEffect=false; break; - case 2: + case ESM::CS_WhenUsed: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenUsed", "When Used")); mAddEffectDialog.constantEffect=false; break; - case 3: + case ESM::CS_ConstantEffect: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastConstant", "Cast Constant")); mAddEffectDialog.constantEffect=true; break; diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 8efbf3c8c..c7a67e7cb 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -74,7 +74,7 @@ namespace MWMechanics MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1); } - if(mCastStyle==3) + if(mCastStyle==ESM::CS_ConstantEffect) { enchantment.mData.mCharge=0; } @@ -255,7 +255,7 @@ namespace MWMechanics + (0.125 * creatureStats.getAttribute (ESM::Attribute::Luck).getModified())); float chance2 = 2.5 * getEnchantCost(); - if(mCastStyle==3) + if(mCastStyle==ESM::CS_ConstantEffect) { float constantChance = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentConstantChanceMult")->getFloat(); chance2 /= constantChance; From 1c7b94e94f27df9d8d078db7178109650ccb4cfd Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 16:08:58 +0200 Subject: [PATCH 071/213] Switching in nextCastStyle() is now based on enum CastingStyle. --- apps/openmw/mwmechanics/enchanting.cpp | 49 +++++++++++++++++--------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index c7a67e7cb..25aa0ea64 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -100,38 +100,53 @@ namespace MWMechanics void Enchanting::nextCastStyle() { - mCastStyle++; if (itemEmpty()) { - mCastStyle = 0; + mCastStyle = ESM::CS_WhenUsed; return; } - if ((mObjectType == typeid(ESM::Armor).name())||(mObjectType == typeid(ESM::Clothing).name())) - { - int soulConstAmount = MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->getInt(); + + const bool powerfulSoul = getGemCharge() >= \ + MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->getInt(); + if ((mObjectType == typeid(ESM::Armor).name()) || (mObjectType == typeid(ESM::Clothing).name())) + { // Armor or Clothing switch(mCastStyle) { - case 1: - mCastStyle = 2; - case 3: - if(getGemCharge() Date: Mon, 27 May 2013 18:03:06 +0200 Subject: [PATCH 072/213] Implement movement for creatures (formula is a stub) --- apps/openmw/mwclass/creature.cpp | 53 ++++++++++++++++++++++++++++++++ apps/openmw/mwclass/creature.hpp | 15 +++++++++ 2 files changed, 68 insertions(+) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index a4eda7126..a263af464 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -5,6 +5,7 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/magiceffects.hpp" +#include "../mwmechanics/movement.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" @@ -29,6 +30,7 @@ namespace { MWMechanics::CreatureStats mCreatureStats; MWWorld::ContainerStore mContainerStore; + MWMechanics::Movement mMovement; virtual MWWorld::CustomData *clone() const; }; @@ -47,6 +49,18 @@ namespace MWClass { std::auto_ptr data (new CustomData); + static bool inited = false; + if(!inited) + { + const MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWWorld::Store &gmst = world->getStore().get(); + + fMinWalkSpeedCreature = gmst.find("fMinWalkSpeedCreature"); + fMaxWalkSpeedCreature = gmst.find("fMaxWalkSpeedCreature"); + + inited = true; + } + MWWorld::LiveCellRef *ref = ptr.get(); // creature stats @@ -181,6 +195,42 @@ namespace MWClass return true; } + float Creature::getSpeed(const MWWorld::Ptr &ptr) const + { + MWMechanics::CreatureStats& stats = getCreatureStats(ptr); + float walkSpeed = fMinWalkSpeedCreature->getFloat() + 0.01 * stats.getAttribute(ESM::Attribute::Speed).getModified() + * (fMaxWalkSpeedCreature->getFloat() - fMinWalkSpeedCreature->getFloat()); + /// \todo what about the rest? + return walkSpeed; + } + + MWMechanics::Movement& Creature::getMovementSettings (const MWWorld::Ptr& ptr) const + { + ensureCustomData (ptr); + + return dynamic_cast (*ptr.getRefData().getCustomData()).mMovement; + } + + Ogre::Vector3 Creature::getMovementVector (const MWWorld::Ptr& ptr) const + { + MWMechanics::Movement &movement = getMovementSettings(ptr); + Ogre::Vector3 vec(movement.mPosition); + movement.mPosition[0] = 0.0f; + movement.mPosition[1] = 0.0f; + movement.mPosition[2] = 0.0f; + return vec; + } + + Ogre::Vector3 Creature::getRotationVector (const MWWorld::Ptr& ptr) const + { + MWMechanics::Movement &movement = getMovementSettings(ptr); + Ogre::Vector3 vec(movement.mRotation); + movement.mRotation[0] = 0.0f; + movement.mRotation[1] = 0.0f; + movement.mRotation[2] = 0.0f; + return vec; + } + MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::Ptr& ptr) const { MWWorld::LiveCellRef *ref = @@ -249,4 +299,7 @@ namespace MWClass return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell); } + + const ESM::GameSetting* Creature::fMinWalkSpeedCreature; + const ESM::GameSetting* Creature::fMaxWalkSpeedCreature; } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index b5657e265..5c30004cd 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -12,6 +12,9 @@ namespace MWClass virtual MWWorld::Ptr copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const; + static const ESM::GameSetting *fMinWalkSpeedCreature; + static const ESM::GameSetting *fMaxWalkSpeedCreature; + public: virtual std::string getId (const MWWorld::Ptr& ptr) const; @@ -66,6 +69,18 @@ namespace MWClass virtual bool isPersistent (const MWWorld::Ptr& ptr) const; + virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; + ///< Return desired movement. + + virtual Ogre::Vector3 getMovementVector (const MWWorld::Ptr& ptr) const; + ///< Return desired movement vector (determined based on movement settings, + /// stance and stats). + + virtual Ogre::Vector3 getRotationVector (const MWWorld::Ptr& ptr) const; + ///< Return desired rotations, as euler angles. + + float getSpeed (const MWWorld::Ptr& ptr) const; + static void registerSelf(); virtual std::string getModel(const MWWorld::Ptr &ptr) const; From ebc1fdd017dfadcc45326bca8e6e4ee0ec330485 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Mon, 27 May 2013 09:05:42 -0700 Subject: [PATCH 073/213] AIWander Patch - fixed another possibility of a bug occuring, best to fix it now then wait until it happens. --- apps/openmw/mwmechanics/aiwander.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 4f7b69016..0a7815ca4 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -92,7 +92,10 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) mCellX = actor.getCell()->mCell->mData.mX; mCellY = actor.getCell()->mCell->mData.mY; - if(mDistance && !mPathgrid->mPoints.empty()) + if(mPathgrid->mPoints.empty()) + mDistance = 0; + + if(mDistance) { mXCell = 0; mYCell = 0; @@ -126,10 +129,9 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) } mCurrentNode = mAllowedNodes[index]; mAllowedNodes.erase(mAllowedNodes.begin() + index); - if(mAllowedNodes.empty()) - mDistance = 0; } - else + + if(mAllowedNodes.empty()) mDistance = 0; } } From 9a9b075a02f55047ce861a5a20872f9f5dc5341d Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 18:08:12 +0200 Subject: [PATCH 074/213] Correct cast cost for enchantments. --- apps/openmw/mwgui/enchantingdialog.cpp | 2 +- apps/openmw/mwmechanics/enchanting.cpp | 18 ++++++++++++++++++ apps/openmw/mwmechanics/enchanting.hpp | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 86bdc25fc..8353cf99e 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -66,7 +66,7 @@ namespace MWGui mCharge->setCaption(boost::lexical_cast(mEnchanting.getGemCharge())); - mCastCost->setCaption(boost::lexical_cast(mEnchanting.getEnchantCost())); + mCastCost->setCaption(boost::lexical_cast(mEnchanting.getCastCost())); mPrice->setCaption(boost::lexical_cast(mEnchanting.getEnchantPrice())); diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 25aa0ea64..95d7694dc 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -206,6 +206,24 @@ namespace MWMechanics return enchantmentCost; } + + float Enchanting::getCastCost() const + { + const float enchantCost = getEnchantCost(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWMechanics::NpcStats &stats = MWWorld::Class::get(player).getNpcStats(player); + int eSkill = stats.getSkill(ESM::Skill::Enchant).getModified(); + + /* + * Each point of enchant skill above/under 10 subtracts/adds + * one percent of enchantment cost while minimum is 1. + */ + const float castCost = enchantCost - (enchantCost / 100) * (eSkill - 10); + + return (castCost < 1) ? 1 : castCost; + } + + int Enchanting::getEnchantPrice() const { if(mEnchanter.isEmpty()) diff --git a/apps/openmw/mwmechanics/enchanting.hpp b/apps/openmw/mwmechanics/enchanting.hpp index a04bd86e9..fefabd308 100644 --- a/apps/openmw/mwmechanics/enchanting.hpp +++ b/apps/openmw/mwmechanics/enchanting.hpp @@ -37,6 +37,7 @@ namespace MWMechanics void nextCastStyle(); //Set enchant type to next possible type (for mOldItemPtr object) int getCastStyle() const; float getEnchantCost() const; + float getCastCost() const; int getEnchantPrice() const; float getMaxEnchantValue() const; int getGemCharge() const; From 4e17bc1499e64fd9aee851b9dc91a3a606b261a2 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 20:16:57 +0200 Subject: [PATCH 075/213] Fix for display of cast cost decimal value --- apps/openmw/mwgui/enchantingdialog.cpp | 4 +++- apps/openmw/mwmechanics/enchanting.cpp | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 8353cf99e..7f71716ed 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -66,7 +66,9 @@ namespace MWGui mCharge->setCaption(boost::lexical_cast(mEnchanting.getGemCharge())); - mCastCost->setCaption(boost::lexical_cast(mEnchanting.getCastCost())); + std::stringstream castCost; + castCost << std::setprecision(1) << std::fixed << mEnchanting.getCastCost(); + mCastCost->setCaption(boost::lexical_cast(castCost.str())); mPrice->setCaption(boost::lexical_cast(mEnchanting.getEnchantPrice())); diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 95d7694dc..821df8fba 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -209,6 +209,9 @@ namespace MWMechanics float Enchanting::getCastCost() const { + if (mCastStyle == ESM::CS_ConstantEffect) + return 0; + const float enchantCost = getEnchantCost(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWMechanics::NpcStats &stats = MWWorld::Class::get(player).getNpcStats(player); From b40e24c50c5461892911d30ed997b49fc1d07ba0 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 20:23:04 +0200 Subject: [PATCH 076/213] Refactorization --- apps/openmw/mwgui/enchantingdialog.cpp | 12 +++---- apps/openmw/mwmechanics/enchanting.cpp | 44 +++++++++++++------------- apps/openmw/mwmechanics/enchanting.hpp | 2 +- components/esm/defs.hpp | 8 ++--- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 7f71716ed..0db577de2 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -61,7 +61,7 @@ namespace MWGui void EnchantingDialog::updateLabels() { std::stringstream enchantCost; - enchantCost << std::setprecision(1) << std::fixed << mEnchanting.getEnchantCost(); + enchantCost << std::setprecision(1) << std::fixed << mEnchanting.getEnchantPoints(); mEnchantmentPoints->setCaption(enchantCost.str() + " / " + boost::lexical_cast(mEnchanting.getMaxEnchantValue())); mCharge->setCaption(boost::lexical_cast(mEnchanting.getGemCharge())); @@ -74,19 +74,19 @@ namespace MWGui switch(mEnchanting.getCastStyle()) { - case ESM::CS_CastOnce: + case ESM::CastingStyle_CastOnce: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce","Cast Once")); mAddEffectDialog.constantEffect=false; break; - case ESM::CS_WhenStrikes: + case ESM::CastingStyle_WhenStrikes: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenStrikes", "When Strikes")); mAddEffectDialog.constantEffect=false; break; - case ESM::CS_WhenUsed: + case ESM::CastingStyle_WhenUsed: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenUsed", "When Used")); mAddEffectDialog.constantEffect=false; break; - case ESM::CS_ConstantEffect: + case ESM::CastingStyle_ConstantEffect: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastConstant", "Cast Constant")); mAddEffectDialog.constantEffect=true; break; @@ -280,7 +280,7 @@ namespace MWGui return; } - if (mEnchanting.getEnchantCost() > mEnchanting.getMaxEnchantValue()) + if (mEnchanting.getEnchantPoints() > mEnchanting.getMaxEnchantValue()) { MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage29}"); return; diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 821df8fba..5be0d83e7 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -12,7 +12,7 @@ namespace MWMechanics { Enchanting::Enchanting(): - mCastStyle(ESM::CS_CastOnce) + mCastStyle(ESM::CastingStyle_CastOnce) {} void Enchanting::setOldItem(MWWorld::Ptr oldItem) @@ -74,12 +74,12 @@ namespace MWMechanics MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1); } - if(mCastStyle==ESM::CS_ConstantEffect) + if(mCastStyle==ESM::CastingStyle_ConstantEffect) { enchantment.mData.mCharge=0; } enchantment.mData.mType = mCastStyle; - enchantment.mData.mCost = getEnchantCost(); + enchantment.mData.mCost = getEnchantPoints(); enchantment.mEffects = mEffectList; const ESM::Enchantment *enchantmentPtr = MWBase::Environment::get().getWorld()->createRecord (enchantment); @@ -102,7 +102,7 @@ namespace MWMechanics { if (itemEmpty()) { - mCastStyle = ESM::CS_WhenUsed; + mCastStyle = ESM::CastingStyle_WhenUsed; return; } @@ -112,12 +112,12 @@ namespace MWMechanics { // Armor or Clothing switch(mCastStyle) { - case ESM::CS_WhenUsed: + case ESM::CastingStyle_WhenUsed: if (powerfulSoul) - mCastStyle = ESM::CS_ConstantEffect; + mCastStyle = ESM::CastingStyle_ConstantEffect; return; default: // takes care of Constant effect too - mCastStyle = ESM::CS_WhenUsed; + mCastStyle = ESM::CastingStyle_WhenUsed; return; } } @@ -125,28 +125,28 @@ namespace MWMechanics { // Weapon switch(mCastStyle) { - case ESM::CS_WhenStrikes: - mCastStyle = ESM::CS_WhenUsed; + case ESM::CastingStyle_WhenStrikes: + mCastStyle = ESM::CastingStyle_WhenUsed; return; - case ESM::CS_WhenUsed: + case ESM::CastingStyle_WhenUsed: if (powerfulSoul) - mCastStyle = ESM::CS_ConstantEffect; + mCastStyle = ESM::CastingStyle_ConstantEffect; else - mCastStyle = ESM::CS_WhenStrikes; + mCastStyle = ESM::CastingStyle_WhenStrikes; return; default: // takes care of Constant effect too - mCastStyle = ESM::CS_WhenStrikes; + mCastStyle = ESM::CastingStyle_WhenStrikes; return; } } else if(mObjectType == typeid(ESM::Book).name()) { // Scroll or Book - mCastStyle = ESM::CS_CastOnce; + mCastStyle = ESM::CastingStyle_CastOnce; return; } // Fail case - mCastStyle = ESM::CS_CastOnce; + mCastStyle = ESM::CastingStyle_CastOnce; } /* @@ -163,7 +163,7 @@ namespace MWMechanics * * Formula on UESPWiki is not entirely correct. */ - float Enchanting::getEnchantCost() const + float Enchanting::getEnchantPoints() const { if (mEffectList.mList.empty()) // No effects added, cost = 0 @@ -184,7 +184,7 @@ namespace MWMechanics magMax = (it->mMagnMax == 0) ? 1 : it->mMagnMax; area = (it->mArea == 0) ? 1 : it->mArea; - if (mCastStyle == ESM::CS_ConstantEffect) + if (mCastStyle == ESM::CastingStyle_ConstantEffect) { magnitudeCost = (magMin + magMax) * baseCost * 2.5; } @@ -209,10 +209,10 @@ namespace MWMechanics float Enchanting::getCastCost() const { - if (mCastStyle == ESM::CS_ConstantEffect) + if (mCastStyle == ESM::CastingStyle_ConstantEffect) return 0; - const float enchantCost = getEnchantCost(); + const float enchantCost = getEnchantPoints(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWMechanics::NpcStats &stats = MWWorld::Class::get(player).getNpcStats(player); int eSkill = stats.getSkill(ESM::Skill::Enchant).getModified(); @@ -233,7 +233,7 @@ namespace MWMechanics return 0; float priceMultipler = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentValueMult")->getFloat(); - int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mEnchanter, (getEnchantCost() * priceMultipler), true); + int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mEnchanter, (getEnchantPoints() * priceMultipler), true); return price; } @@ -290,8 +290,8 @@ namespace MWMechanics (0.25 * creatureStats.getAttribute (ESM::Attribute::Intelligence).getModified()) + (0.125 * creatureStats.getAttribute (ESM::Attribute::Luck).getModified())); - float chance2 = 2.5 * getEnchantCost(); - if(mCastStyle==ESM::CS_ConstantEffect) + float chance2 = 2.5 * getEnchantPoints(); + if(mCastStyle==ESM::CastingStyle_ConstantEffect) { float constantChance = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentConstantChanceMult")->getFloat(); chance2 /= constantChance; diff --git a/apps/openmw/mwmechanics/enchanting.hpp b/apps/openmw/mwmechanics/enchanting.hpp index fefabd308..4321e5bd6 100644 --- a/apps/openmw/mwmechanics/enchanting.hpp +++ b/apps/openmw/mwmechanics/enchanting.hpp @@ -36,7 +36,7 @@ namespace MWMechanics bool create(); //Return true if created, false if failed. void nextCastStyle(); //Set enchant type to next possible type (for mOldItemPtr object) int getCastStyle() const; - float getEnchantCost() const; + float getEnchantPoints() const; float getCastCost() const; int getEnchantPrice() const; float getMaxEnchantValue() const; diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index 7586413a6..cf7b586fc 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -26,10 +26,10 @@ enum RangeType // Casting style (in enchanting) enum CastingStyle { - CS_CastOnce = 0, - CS_WhenStrikes = 1, - CS_WhenUsed = 2, - CS_ConstantEffect = 3 + CastingStyle_CastOnce = 0, + CastingStyle_WhenStrikes = 1, + CastingStyle_WhenUsed = 2, + CastingStyle_ConstantEffect = 3 }; #pragma pack(push) From dbbc96f60032ed42ea427982b7206cf5922a2c7d Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Mon, 27 May 2013 11:44:46 -0700 Subject: [PATCH 077/213] AIWander Segmentation Fault Fix - Fixes the segmentation fault that used to occur when there was no pathgrid in the cell and a range was passed to AIWander. --- apps/openmw/mwmechanics/aiwander.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 0a7815ca4..46c5598cc 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -38,6 +38,7 @@ MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const srand(time(NULL)); mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp(); mPlayedIdle = 0; + mPathgrid = NULL; mIdleChanceMultiplier = MWBase::Environment::get().getWorld()->getStore().get().find("fIdleChanceMultiplier")->getFloat(); @@ -92,7 +93,9 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) mCellX = actor.getCell()->mCell->mData.mX; mCellY = actor.getCell()->mCell->mData.mY; - if(mPathgrid->mPoints.empty()) + if(!mPathgrid) + mDistance = 0; + else if(mPathgrid->mPoints.empty()) mDistance = 0; if(mDistance) From 7a4a386cbe069c5e127efc97241dc9aa38ecd4ce Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Mon, 27 May 2013 20:47:53 +0200 Subject: [PATCH 078/213] Removal of tab characters. --- apps/openmw/mwmechanics/enchanting.cpp | 88 +++++++++++++------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 5be0d83e7..05d4c635f 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -107,7 +107,7 @@ namespace MWMechanics } const bool powerfulSoul = getGemCharge() >= \ - MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->getInt(); + MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->getInt(); if ((mObjectType == typeid(ESM::Armor).name()) || (mObjectType == typeid(ESM::Clothing).name())) { // Armor or Clothing switch(mCastStyle) @@ -126,17 +126,17 @@ namespace MWMechanics switch(mCastStyle) { case ESM::CastingStyle_WhenStrikes: - mCastStyle = ESM::CastingStyle_WhenUsed; - return; + mCastStyle = ESM::CastingStyle_WhenUsed; + return; case ESM::CastingStyle_WhenUsed: - if (powerfulSoul) - mCastStyle = ESM::CastingStyle_ConstantEffect; - else - mCastStyle = ESM::CastingStyle_WhenStrikes; - return; + if (powerfulSoul) + mCastStyle = ESM::CastingStyle_ConstantEffect; + else + mCastStyle = ESM::CastingStyle_WhenStrikes; + return; default: // takes care of Constant effect too - mCastStyle = ESM::CastingStyle_WhenStrikes; - return; + mCastStyle = ESM::CastingStyle_WhenStrikes; + return; } } else if(mObjectType == typeid(ESM::Book).name()) @@ -149,25 +149,25 @@ namespace MWMechanics mCastStyle = ESM::CastingStyle_CastOnce; } - /* - * Vanilla enchant cost formula: - * - * Touch/Self: (min + max) * baseCost * 0.025 * duration + area * baseCost * 0.025 - * Target: 1.5 * ((min + max) * baseCost * 0.025 * duration + area * baseCost * 0.025) - * Constant eff: (min + max) * baseCost * 2.5 + area * baseCost * 0.025 - * - * For multiple effects - cost of each effect is multiplied by number of effects that follows +1. - * - * Note: Minimal value inside formula for 'min' and 'max' is 1. So in vanilla: - * (0 + 0) == (1 + 0) == (1 + 1) => 2 or (2 + 0) == (1 + 2) => 3 - * - * Formula on UESPWiki is not entirely correct. - */ + /* + * Vanilla enchant cost formula: + * + * Touch/Self: (min + max) * baseCost * 0.025 * duration + area * baseCost * 0.025 + * Target: 1.5 * ((min + max) * baseCost * 0.025 * duration + area * baseCost * 0.025) + * Constant eff: (min + max) * baseCost * 2.5 + area * baseCost * 0.025 + * + * For multiple effects - cost of each effect is multiplied by number of effects that follows +1. + * + * Note: Minimal value inside formula for 'min' and 'max' is 1. So in vanilla: + * (0 + 0) == (1 + 0) == (1 + 1) => 2 or (2 + 0) == (1 + 2) => 3 + * + * Formula on UESPWiki is not entirely correct. + */ float Enchanting::getEnchantPoints() const { - if (mEffectList.mList.empty()) - // No effects added, cost = 0 - return 0; + if (mEffectList.mList.empty()) + // No effects added, cost = 0 + return 0; const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); std::vector mEffects = mEffectList.mList; @@ -186,18 +186,18 @@ namespace MWMechanics if (mCastStyle == ESM::CastingStyle_ConstantEffect) { - magnitudeCost = (magMin + magMax) * baseCost * 2.5; + magnitudeCost = (magMin + magMax) * baseCost * 2.5; } else { - magnitudeCost = (magMin + magMax) * it->mDuration * baseCost * 0.025; - if(it->mRange == ESM::RT_Target) - magnitudeCost *= 1.5; + magnitudeCost = (magMin + magMax) * it->mDuration * baseCost * 0.025; + if(it->mRange == ESM::RT_Target) + magnitudeCost *= 1.5; } areaCost = area * 0.025 * baseCost; if (it->mRange == ESM::RT_Target) - areaCost *= 1.5; + areaCost *= 1.5; enchantmentCost += (magnitudeCost + areaCost) * effectsLeftCnt; --effectsLeftCnt; @@ -209,21 +209,21 @@ namespace MWMechanics float Enchanting::getCastCost() const { - if (mCastStyle == ESM::CastingStyle_ConstantEffect) - return 0; + if (mCastStyle == ESM::CastingStyle_ConstantEffect) + return 0; - const float enchantCost = getEnchantPoints(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - MWMechanics::NpcStats &stats = MWWorld::Class::get(player).getNpcStats(player); - int eSkill = stats.getSkill(ESM::Skill::Enchant).getModified(); + const float enchantCost = getEnchantPoints(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWMechanics::NpcStats &stats = MWWorld::Class::get(player).getNpcStats(player); + int eSkill = stats.getSkill(ESM::Skill::Enchant).getModified(); - /* - * Each point of enchant skill above/under 10 subtracts/adds - * one percent of enchantment cost while minimum is 1. - */ - const float castCost = enchantCost - (enchantCost / 100) * (eSkill - 10); + /* + * Each point of enchant skill above/under 10 subtracts/adds + * one percent of enchantment cost while minimum is 1. + */ + const float castCost = enchantCost - (enchantCost / 100) * (eSkill - 10); - return (castCost < 1) ? 1 : castCost; + return (castCost < 1) ? 1 : castCost; } From 9a4392707849456594ebbf17d8dc0bfe040a84a8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 28 May 2013 03:15:13 +0200 Subject: [PATCH 079/213] Fix weapons not appearing in Enchantable filter --- apps/openmw/mwgui/sortfilteritemmodel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index b88ec7c0b..3cf514dc5 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -106,6 +106,7 @@ namespace MWGui if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted || (base.getTypeName() != typeid(ESM::Armor).name() && base.getTypeName() != typeid(ESM::Clothing).name() + && base.getTypeName() != typeid(ESM::Weapon).name() && base.getTypeName() != typeid(ESM::Book).name()))) return false; if ((mFilter & Filter_OnlyEnchantable) && base.getTypeName() == typeid(ESM::Book).name() From dc17fa16365fd3697d9443e898005bf9130fd05d Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Wed, 29 May 2013 00:01:18 +0200 Subject: [PATCH 080/213] Removal of duplicit enumeration and unnecessary conditions. --- apps/openmw/mwgui/enchantingdialog.cpp | 8 ++--- apps/openmw/mwmechanics/enchanting.cpp | 42 ++++++++++++-------------- apps/openmw/mwmechanics/enchanting.hpp | 1 - components/esm/defs.hpp | 9 ------ 4 files changed, 23 insertions(+), 37 deletions(-) diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 0db577de2..98ba8ec2f 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -74,19 +74,19 @@ namespace MWGui switch(mEnchanting.getCastStyle()) { - case ESM::CastingStyle_CastOnce: + case ESM::Enchantment::CastOnce: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce","Cast Once")); mAddEffectDialog.constantEffect=false; break; - case ESM::CastingStyle_WhenStrikes: + case ESM::Enchantment::WhenStrikes: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenStrikes", "When Strikes")); mAddEffectDialog.constantEffect=false; break; - case ESM::CastingStyle_WhenUsed: + case ESM::Enchantment::WhenUsed: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenUsed", "When Used")); mAddEffectDialog.constantEffect=false; break; - case ESM::CastingStyle_ConstantEffect: + case ESM::Enchantment::ConstantEffect: mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastConstant", "Cast Constant")); mAddEffectDialog.constantEffect=true; break; diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 05d4c635f..faa450df7 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -12,7 +12,7 @@ namespace MWMechanics { Enchanting::Enchanting(): - mCastStyle(ESM::CastingStyle_CastOnce) + mCastStyle(ESM::Enchantment::CastOnce) {} void Enchanting::setOldItem(MWWorld::Ptr oldItem) @@ -74,7 +74,7 @@ namespace MWMechanics MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1); } - if(mCastStyle==ESM::CastingStyle_ConstantEffect) + if(mCastStyle==ESM::Enchantment::ConstantEffect) { enchantment.mData.mCharge=0; } @@ -102,7 +102,7 @@ namespace MWMechanics { if (itemEmpty()) { - mCastStyle = ESM::CastingStyle_WhenUsed; + mCastStyle = ESM::Enchantment::WhenUsed; return; } @@ -112,12 +112,12 @@ namespace MWMechanics { // Armor or Clothing switch(mCastStyle) { - case ESM::CastingStyle_WhenUsed: + case ESM::Enchantment::WhenUsed: if (powerfulSoul) - mCastStyle = ESM::CastingStyle_ConstantEffect; + mCastStyle = ESM::Enchantment::ConstantEffect; return; default: // takes care of Constant effect too - mCastStyle = ESM::CastingStyle_WhenUsed; + mCastStyle = ESM::Enchantment::WhenUsed; return; } } @@ -125,28 +125,28 @@ namespace MWMechanics { // Weapon switch(mCastStyle) { - case ESM::CastingStyle_WhenStrikes: - mCastStyle = ESM::CastingStyle_WhenUsed; + case ESM::Enchantment::WhenStrikes: + mCastStyle = ESM::Enchantment::WhenUsed; return; - case ESM::CastingStyle_WhenUsed: + case ESM::Enchantment::WhenUsed: if (powerfulSoul) - mCastStyle = ESM::CastingStyle_ConstantEffect; + mCastStyle = ESM::Enchantment::ConstantEffect; else - mCastStyle = ESM::CastingStyle_WhenStrikes; + mCastStyle = ESM::Enchantment::WhenStrikes; return; default: // takes care of Constant effect too - mCastStyle = ESM::CastingStyle_WhenStrikes; + mCastStyle = ESM::Enchantment::WhenStrikes; return; } } else if(mObjectType == typeid(ESM::Book).name()) { // Scroll or Book - mCastStyle = ESM::CastingStyle_CastOnce; + mCastStyle = ESM::Enchantment::CastOnce; return; } // Fail case - mCastStyle = ESM::CastingStyle_CastOnce; + mCastStyle = ESM::Enchantment::CastOnce; } /* @@ -184,7 +184,7 @@ namespace MWMechanics magMax = (it->mMagnMax == 0) ? 1 : it->mMagnMax; area = (it->mArea == 0) ? 1 : it->mArea; - if (mCastStyle == ESM::CastingStyle_ConstantEffect) + if (mCastStyle == ESM::Enchantment::ConstantEffect) { magnitudeCost = (magMin + magMax) * baseCost * 2.5; } @@ -209,7 +209,7 @@ namespace MWMechanics float Enchanting::getCastCost() const { - if (mCastStyle == ESM::CastingStyle_ConstantEffect) + if (mCastStyle == ESM::Enchantment::ConstantEffect) return 0; const float enchantCost = getEnchantPoints(); @@ -256,16 +256,12 @@ namespace MWMechanics } bool Enchanting::soulEmpty() const { - if (mSoulGemPtr.isEmpty()) - return true; - return false; + return mSoulGemPtr.isEmpty(); } bool Enchanting::itemEmpty() const { - if(mOldItemPtr.isEmpty()) - return true; - return false; + return mOldItemPtr.isEmpty(); } void Enchanting::setSelfEnchanting(bool selfEnchanting) @@ -291,7 +287,7 @@ namespace MWMechanics + (0.125 * creatureStats.getAttribute (ESM::Attribute::Luck).getModified())); float chance2 = 2.5 * getEnchantPoints(); - if(mCastStyle==ESM::CastingStyle_ConstantEffect) + if(mCastStyle==ESM::Enchantment::ConstantEffect) { float constantChance = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentConstantChanceMult")->getFloat(); chance2 /= constantChance; diff --git a/apps/openmw/mwmechanics/enchanting.hpp b/apps/openmw/mwmechanics/enchanting.hpp index 4321e5bd6..a25fd43ab 100644 --- a/apps/openmw/mwmechanics/enchanting.hpp +++ b/apps/openmw/mwmechanics/enchanting.hpp @@ -3,7 +3,6 @@ #include #include "../mwworld/ptr.hpp" #include -#include #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" namespace MWMechanics diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index cf7b586fc..bd86f9ba0 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -23,15 +23,6 @@ enum RangeType RT_Target = 2 }; -// Casting style (in enchanting) -enum CastingStyle -{ - CastingStyle_CastOnce = 0, - CastingStyle_WhenStrikes = 1, - CastingStyle_WhenUsed = 2, - CastingStyle_ConstantEffect = 3 -}; - #pragma pack(push) #pragma pack(1) From 35fb9b669a7cf6a8371e8d19631bd1339bab3884 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Wed, 29 May 2013 06:38:35 -0500 Subject: [PATCH 081/213] Final details implemented Png icons, alignments fixed. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/columns.hpp | 4 +- apps/opencs/view/doc/viewmanager.cpp | 4 + .../view/world/recordstatusdelegate.cpp | 111 ++++++++++++++++++ .../view/world/recordstatusdelegate.hpp | 45 +++++++ files/opencs/resources.qrc | 3 + 7 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 apps/opencs/view/world/recordstatusdelegate.cpp create mode 100644 apps/opencs/view/world/recordstatusdelegate.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 9787719af..d30c92350 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -61,7 +61,7 @@ opencs_units (view/world ) opencs_units_noqt (view/world - dialoguesubview util subviews enumdelegate vartypedelegate scripthighlighter + dialoguesubview util subviews enumdelegate vartypedelegate scripthighlighter recordstatusdelegate ) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 8cc435f3a..e71e633a4 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -41,7 +41,8 @@ namespace CSMWorld Display_ArmorType, Display_ClothingType, Display_CreatureType, - Display_WeaponType + Display_WeaponType, + Display_RecordState }; std::string mTitle; diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index f1d8d4ae6..649ae192f 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -53,7 +53,7 @@ namespace CSMWorld template struct RecordStateColumn : public Column { - RecordStateColumn() : Column ("*", ColumnBase::Display_Integer) {} + RecordStateColumn() : Column ("*", ColumnBase::Display_RecordState) {} virtual QVariant get (const Record& record) const { @@ -775,4 +775,4 @@ namespace CSMWorld }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index d044098fe..97dd8b997 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -12,6 +12,7 @@ #include "../world/util.hpp" #include "../world/enumdelegate.hpp" #include "../world/vartypedelegate.hpp" +#include "../world/recordstatusdelegate.hpp" #include "view.hpp" @@ -117,6 +118,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_WeaponType, new CSVWorld::EnumDelegateFactory (sWeaponTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_RecordState, + new CSVWorld::RecordStatusDelegateFactory() ); } CSVDoc::ViewManager::~ViewManager() diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp new file mode 100644 index 000000000..c9dbff4f5 --- /dev/null +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -0,0 +1,111 @@ +#include "recordstatusdelegate.hpp" +#include +#include +#include +#include + +#include + +CSVWorld::RecordStatusDelegate::RecordStatusDelegate(QUndoStack &undoStack, QObject *parent) + : CommandDelegate (undoStack, parent) +{ + mModifiedIcon = new QIcon (":./modified.png"); + mAddedIcon = new QIcon (":./added.png"); + mDeletedIcon = new QIcon (":./removed.png"); + mIconSize = 16; + + //Offset values are most likely device-dependent. + //Need to replace with device-independent references. + mTextTopOffset = -1; + mTextLeftOffset = 3; + mIconTopOffset = -3; + mIconLeftOffset = 0; + + mStatusDisplay = 0; //icons and text by default +} + +void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + painter->save(); + + QFont font = QApplication::font(); + font.setPointSize(10); + + QFontMetrics fm(font); + + QString text = ""; + QIcon *icon = 0; + + switch (index.data().toInt()) + { + case 0: // State_BaseOnly + text = "base"; + break; + + case 1: // State_Modified + text = "modified"; + icon = mModifiedIcon; + break; + + case 2: // State_Modified_Only + text = "added"; + icon = mAddedIcon; + break; + + case 3: // State_Deleted + + case 4: // State_Erased + text = "deleted"; + icon = mDeletedIcon; + break; + + default: + break; + } + + QRect textRect = option.rect; + QRect iconRect = option.rect; + + //for icon-only (1), default option.rect centers icon left-to-right + //otherwise, size option.rect to fit the icon, forcing left-alignment with text + iconRect.setTop (iconRect.top() + mIconTopOffset); + iconRect.setBottom (iconRect.top() + mIconSize); + + if (mStatusDisplay == 0 && (icon) ) + { + iconRect.setRight (iconRect.left() + mIconSize); + textRect.setLeft (iconRect.right() + (mIconSize/4) * 3); + textRect.setRight (textRect.left() + fm.width(text)); + } + else + textRect.setLeft (textRect.left() + mTextLeftOffset ); + + textRect.setTop (textRect.top() + ((option.rect.height() - fm.height()) / 2) + mTextTopOffset); + + if (mStatusDisplay == 0 || mStatusDisplay == 1) + { + if (icon) + painter->drawPixmap(iconRect.center(),icon->pixmap(mIconSize, mIconSize)); + } + + // icon + text or text only, or force text if no icon exists for status + if (mStatusDisplay == 0 || mStatusDisplay == 2 || !(icon) ) + { + painter->setFont(font); + painter->drawText(textRect,text); + } + + painter->restore(); + +} + +QSize CSVWorld::RecordStatusDelegate::sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return QSize(); +} + +CSVWorld::CommandDelegate *CSVWorld::RecordStatusDelegateFactory::makeDelegate (QUndoStack& undoStack, + QObject *parent) const +{ + return new RecordStatusDelegate (undoStack, parent); +} diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp new file mode 100644 index 000000000..a2ec34822 --- /dev/null +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -0,0 +1,45 @@ +#ifndef RECORDSTATUSDELEGATE_H +#define RECORDSTATUSDELEGATE_H + +#include "util.hpp" + +class QIcon; + +namespace CSVWorld +{ + class RecordStatusDelegate : public CommandDelegate + { + + QIcon *mModifiedIcon; + QIcon *mAddedIcon; + QIcon *mDeletedIcon; + int mStatusDisplay; + + int mIconSize; + int mIconTopOffset; + int mIconLeftOffset; + int mTextTopOffset; + int mTextLeftOffset; + + public: + explicit RecordStatusDelegate(QUndoStack& undoStack, QObject *parent = 0); + + void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const; + + }; + + class RecordStatusDelegateFactory : public CommandDelegateFactory + { + //std::vector > mValues; + + public: + + virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; + ///< The ownership of the returned CommandDelegate is transferred to the caller. + + }; +} +#endif // RECORDSTATUSDELEGATE_H + diff --git a/files/opencs/resources.qrc b/files/opencs/resources.qrc index ecfab44a2..e2ad0ffd6 100644 --- a/files/opencs/resources.qrc +++ b/files/opencs/resources.qrc @@ -1,5 +1,8 @@ opencs.png + added.png + modified.png + removed.png From 94db7cdcfebbc386e1ba5cdc0c08319b5ff091a8 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Wed, 29 May 2013 12:45:15 -0500 Subject: [PATCH 082/213] Added png's of icons --- files/opencs/added.png | Bin 0 -> 1223 bytes files/opencs/modified.png | Bin 0 -> 1855 bytes files/opencs/removed.png | Bin 0 -> 1490 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 files/opencs/added.png create mode 100644 files/opencs/modified.png create mode 100644 files/opencs/removed.png diff --git a/files/opencs/added.png b/files/opencs/added.png new file mode 100644 index 0000000000000000000000000000000000000000..456966a9c953555eb33677f2c6ad507b01b58529 GIT binary patch literal 1223 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D(<+r!7#%P+tuAjnTgR~zU^H8nLI9W7sfA6q+Xdq+DLS0^_Q7f&yD{{SB! zUr%KfB~ek)r%#_sNl7UxD|q{Q+Sppz+1q+~yDKRvNk~Zi|Nmc3PEJu#-rB|z=n;2M zS1%tAMJ1s1a+X%+);3o54t8?#axQL8<`!lSj`mJ2jzBNFx;s0$ILOJ%%F4<(Iy;z} znOIp{+SpnH!$DR~Mp{PN$k@=>#K^?d$jsct+``n#+QP!pOiD^pLQ-5`Ur$q0Lql8c)Q2qYxLWn`qZwY9{=#q{*_OiWC~CB)S=)cN`O)YMe@`1q8SmH7C0 z6%^!oczA#ob8~Y`OG|Nba*B$IaBy%434tPjg@r{xKtM=Hh@G9Cjg74;gmninj5tby z{DO7w|GoeB?|t0`H|1vn#Tb*k-CcBc-7Q=VvL>2>6&TkNA4N5OK$N4p$&#d4yc`JapLjb($+eiOJ6f?2P<3F(sRG(O#U?g z+mFI`KbGx%_x+vC^WA$Z?B+9HxR9|;Aos0oSoZR>_paW(o4UO;YJSO$I0Wq@uT64 zCzDl<`f^@AQ_W*%aQTpk`$W$=p(7&p%`P_%?KJ%H`&Yvb$-H|Q=cZyh-=xJQ&yWCe8=nQCkc_FmAZw+ z$+oj&o0DEv?~GZI^PJn>V8yjhx2HPo+!L&I=v|z`q#f^{Gyho1tJHXZ_lA0b9=|_} zGd?89^QkH;$R4`5QP9G!X>zb~K^0T_bGHY7c=T4eEvRBNy~%OHbVo=}LlI|q=wjEC z;S0PrEz&T0CAI$7uXi=((?SBST6u;3U%|yze=%^j@`BKMo>#wq)HDBhXv3y!HR0ps z$)y*V)b4tn>J__n-dQcf^kMyrm-lB!j}VJsDux!5|5;Aviy+ pq&%@Gm7%=6TrV>(yEr+qAXP8FD1G)j8!4b722WQ%mvv4FO#p%Rp2PqE literal 0 HcmV?d00001 diff --git a/files/opencs/modified.png b/files/opencs/modified.png new file mode 100644 index 0000000000000000000000000000000000000000..ca613f9e48f89cd597f9a1296a7b6cd921cb19eb GIT binary patch literal 1855 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 II;Vst04OK`B>(^b literal 0 HcmV?d00001 From 48386789446ba0f09ce055b0edd60b3f3bd0349e Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 29 May 2013 15:59:23 -0700 Subject: [PATCH 083/213] Pathfinding Overhaul - Cleanup, removed unnecessary include, fixed spacing, added a function for clearing a path, overall preperation to begin working on fixing pathfinding. --- apps/openmw/mwmechanics/pathfinding.cpp | 144 +++++++++++++----------- apps/openmw/mwmechanics/pathfinding.hpp | 25 ++-- 2 files changed, 89 insertions(+), 80 deletions(-) diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 62c825be7..6d9089455 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -3,46 +3,48 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "OgreMath.h" + #include #include -#include "boost/tuple/tuple.hpp" -#include "OgreMath.h" namespace { - //helpers functions +//helpers functions float distanceZCorrected(ESM::Pathgrid::Point point,float x,float y,float z) { - return sqrt((point.mX - x)*(point.mX - x)+(point.mY - y)*(point.mY - y)+0.1*(point.mZ - z)*(point.mZ - z)); + return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + 0.1 * (point.mZ - z) * (point.mZ - z)); } float distance(ESM::Pathgrid::Point point,float x,float y,float z) { - return sqrt((point.mX - x)*(point.mX - x)+(point.mY - y)*(point.mY - y)+(point.mZ - z)*(point.mZ - z)); + return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + (point.mZ - z) * (point.mZ - z)); } float distance(ESM::Pathgrid::Point a,ESM::Pathgrid::Point b) { - return sqrt(float(a.mX - b.mX)*(a.mX - b.mX)+(a.mY - b.mY)*(a.mY - b.mY)+(a.mZ - b.mZ)*(a.mZ - b.mZ)); + return sqrt(float(a.mX - b.mX) * (a.mX - b.mX) + (a.mY - b.mY) * (a.mY - b.mY) + (a.mZ - b.mZ) * (a.mZ - b.mZ)); } static float sgn(float a) { - if(a>0) return 1.; - else return -1.; + if(a > 0) return 1.0; + else return -1.0; } int getClosestPoint(const ESM::Pathgrid* grid,float x,float y,float z) { - if(!grid) return -1; - if(grid->mPoints.empty()) return -1; + if(!grid) + return -1; + if(grid->mPoints.empty()) + return -1; float m = distance(grid->mPoints[0],x,y,z); int i0 = 0; - for(unsigned int i=1; imPoints.size();++i) + for(unsigned int i = 1; i < grid->mPoints.size(); ++i) { - if(distance(grid->mPoints[i],x,y,z)mPoints[i],x,y,z) < m) { m = distance(grid->mPoints[i],x,y,z); i0 = i; @@ -55,64 +57,64 @@ namespace boost::property,boost::property > PathGridGraph; typedef boost::property_map::type WeightMap; typedef PathGridGraph::vertex_descriptor PointID; - typedef PathGridGraph::edge_descriptor PointConnectionID; + typedef PathGridGraph::edge_descriptor PointConnectionID; struct found_path {}; /*class goalVisited : public boost::default_astar_visitor - { - public: - goalVisited(PointID goal) : mGoal(goal) {} +{ +public: +goalVisited(PointID goal) : mGoal(goal) {} - void examine_vertex(PointID u, const PathGridGraph g) - { - if(u == mGoal) - throw found_path(); - } - private: - PointID mGoal; - }; +void examine_vertex(PointID u, const PathGridGraph g) +{ +if(u == mGoal) +throw found_path(); +} +private: +PointID mGoal; +}; - class DistanceHeuristic : public boost::atasr_heuristic - { - public: - DistanceHeuristic(const PathGridGraph & l, PointID goal) - : mGraph(l), mGoal(goal) {} +class DistanceHeuristic : public boost::atasr_heuristic +{ +public: +DistanceHeuristic(const PathGridGraph & l, PointID goal) +: mGraph(l), mGoal(goal) {} - float operator()(PointID u) - { - const ESM::Pathgrid::Point & U = mGraph[u]; - const ESM::Pathgrid::Point & V = mGraph[mGoal]; - float dx = U.mX - V.mX; - float dy = U.mY - V.mY; - float dz = U.mZ - V.mZ; - return sqrt(dx * dx + dy * dy + dz * dz); - } - private: - const PathGridGraph & mGraph; - PointID mGoal; - };*/ - - class goalVisited : public boost::default_dijkstra_visitor - { - public: - goalVisited(PointID goal) : mGoal(goal) {} - - void examine_vertex(PointID u, const PathGridGraph g) - { - if(u == mGoal) - throw found_path(); - } - private: - PointID mGoal; - }; +float operator()(PointID u) +{ +const ESM::Pathgrid::Point & U = mGraph[u]; +const ESM::Pathgrid::Point & V = mGraph[mGoal]; +float dx = U.mX - V.mX; +float dy = U.mY - V.mY; +float dz = U.mZ - V.mZ; +return sqrt(dx * dx + dy * dy + dz * dz); +} +private: +const PathGridGraph & mGraph; +PointID mGoal; +};*/ + +class goalVisited : public boost::default_dijkstra_visitor +{ +public: +goalVisited(PointID goal) : mGoal(goal) {} + +void examine_vertex(PointID u, const PathGridGraph g) +{ +if(u == mGoal) +throw found_path(); +} +private: +PointID mGoal; +}; PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCell = 0) { PathGridGraph graph; - for(unsigned int i = 0;imPoints.size();++i) + for(unsigned int i = 0; i < pathgrid->mPoints.size(); ++i) { PointID pID = boost::add_vertex(graph); graph[pID].mX = pathgrid->mPoints[i].mX + xCell; @@ -130,7 +132,6 @@ namespace boost::tie(edge,done) = boost::add_edge(u,v,graph); WeightMap weightmap = boost::get(boost::edge_weight, graph); weightmap[edge] = distance(graph[u],graph[v]); - } return graph; @@ -147,10 +148,10 @@ namespace graph, start, boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))//.weight_map(boost::get(&Edge::distance, graph)) - ); +); } catch(found_path fg) { - for(PointID v = end;; v = p[v]) { + for(PointID v = end; ; v = p[v]) { shortest_path.push_front(graph[v]); if(p[v] == v) break; @@ -170,6 +171,13 @@ namespace MWMechanics mIsPathConstructed = false; } + void PathFinder::clearPath() + { + if(!mPath.empty()) + mPath.clear(); + mIsPathConstructed = false; + } + void PathFinder::buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint, const ESM::Pathgrid* pathGrid,float xCell,float yCell) { @@ -193,9 +201,8 @@ namespace MWMechanics float PathFinder::getZAngleToNext(float x,float y,float z) { if(mPath.empty()) - { - return 0;/// shouldn't happen! - } + return 0; /// shouldn't happen! + ESM::Pathgrid::Point nextPoint = *mPath.begin(); float dX = nextPoint.mX - x; float dY = nextPoint.mY - y; @@ -206,17 +213,16 @@ namespace MWMechanics bool PathFinder::checkIfNextPointReached(float x,float y,float z) { if(mPath.empty()) - { return true; - } + ESM::Pathgrid::Point nextPoint = *mPath.begin(); if(distanceZCorrected(nextPoint,x,y,z) < 20) { mPath.pop_front(); + if(mPath.empty()) - { return true; - } + nextPoint = *mPath.begin(); } return false; @@ -226,8 +232,10 @@ namespace MWMechanics { return mPath; } + bool PathFinder::isPathConstructed() { return mIsPathConstructed; } -} \ No newline at end of file +} + diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index b1bbab37a..dc380afb4 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -8,22 +8,23 @@ namespace MWMechanics { class PathFinder { - public: - PathFinder(); + public: + PathFinder(); - void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint, - const ESM::Pathgrid* pathGrid,float xCell = 0,float yCell = 0); + void clearPath(); + void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint, + const ESM::Pathgrid* pathGrid,float xCell = 0,float yCell = 0); - bool checkIfNextPointReached(float x,float y,float z);//returns true if the last point of the path has been reached. - float getZAngleToNext(float x,float y,float z); + bool checkIfNextPointReached(float x,float y,float z);//returns true if the last point of the path has been reached. + float getZAngleToNext(float x,float y,float z); - std::list getPath(); - bool isPathConstructed(); + std::list getPath(); + bool isPathConstructed(); - private: - std::list mPath; - bool mIsPathConstructed; + private: + std::list mPath; + bool mIsPathConstructed; }; } -#endif \ No newline at end of file +#endif From 96fdaf74109ce79065224d7787ce08563bf8326e Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 29 May 2013 16:10:15 -0700 Subject: [PATCH 084/213] Pathfinding Overhaul - More cleanup. --- apps/openmw/mwmechanics/pathfinding.cpp | 37 +++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 6d9089455..b13bfa7af 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -10,7 +10,7 @@ namespace { -//helpers functions + // helpers functions float distanceZCorrected(ESM::Pathgrid::Point point,float x,float y,float z) { return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + 0.1 * (point.mZ - z) * (point.mZ - z)); @@ -28,8 +28,10 @@ namespace static float sgn(float a) { - if(a > 0) return 1.0; - else return -1.0; + if(a > 0) + return 1.0; + else + return -1.0; } int getClosestPoint(const ESM::Pathgrid* grid,float x,float y,float z) @@ -95,19 +97,20 @@ const PathGridGraph & mGraph; PointID mGoal; };*/ -class goalVisited : public boost::default_dijkstra_visitor -{ -public: -goalVisited(PointID goal) : mGoal(goal) {} + class goalVisited : public boost::default_dijkstra_visitor + { + public: + goalVisited(PointID goal) : mGoal(goal) {} -void examine_vertex(PointID u, const PathGridGraph g) -{ -if(u == mGoal) -throw found_path(); -} -private: -PointID mGoal; -}; + void examine_vertex(PointID u, const PathGridGraph g) + { + if(u == mGoal) + throw found_path(); + } + + private: + PointID mGoal; + }; PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCell = 0) @@ -206,8 +209,8 @@ namespace MWMechanics ESM::Pathgrid::Point nextPoint = *mPath.begin(); float dX = nextPoint.mX - x; float dY = nextPoint.mY - y; - float h = sqrt(dX*dX+dY*dY); - return Ogre::Radian(acos(dY/h)*sgn(asin(dX/h))).valueDegrees(); + float h = sqrt(dX * dX + dY * dY); + return Ogre::Radian(acos(dY / h) * sgn(asin(dX / h))).valueDegrees(); } bool PathFinder::checkIfNextPointReached(float x,float y,float z) From 7b465ae4f1703f19182538658a58d74462d71b96 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 29 May 2013 17:33:33 -0700 Subject: [PATCH 085/213] Pathfinding Overhaul - Even more cleanup and spacing corrections, small renaming (more to come), removed a few unnecessary actions that wasted CPU time and tmp RAM. --- apps/openmw/mwmechanics/pathfinding.cpp | 169 +++++++++--------------- apps/openmw/mwmechanics/pathfinding.hpp | 3 +- 2 files changed, 65 insertions(+), 107 deletions(-) diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index b13bfa7af..e319116f1 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -10,18 +10,36 @@ namespace { - // helpers functions - float distanceZCorrected(ESM::Pathgrid::Point point,float x,float y,float z) + struct found_path {}; + + typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, + boost::property, boost::property > + PathGridGraph; + typedef boost::property_map::type WeightMap; + typedef PathGridGraph::vertex_descriptor PointID; + typedef PathGridGraph::edge_descriptor PointConnectionID; + + class goalVisited : public boost::default_dijkstra_visitor + { + public: + goalVisited(PointID goal) {mGoal = goal;}; + void examine_vertex(PointID u, const PathGridGraph g) {if(u == mGoal) throw found_path();}; + + private: + PointID mGoal; + }; + + float distanceZCorrected(ESM::Pathgrid::Point point, float x, float y, float z) { return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + 0.1 * (point.mZ - z) * (point.mZ - z)); } - float distance(ESM::Pathgrid::Point point,float x,float y,float z) + float distance(ESM::Pathgrid::Point point, float x, float y, float z) { return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + (point.mZ - z) * (point.mZ - z)); } - float distance(ESM::Pathgrid::Point a,ESM::Pathgrid::Point b) + float distance(ESM::Pathgrid::Point a, ESM::Pathgrid::Point b) { return sqrt(float(a.mX - b.mX) * (a.mX - b.mX) + (a.mY - b.mY) * (a.mY - b.mY) + (a.mZ - b.mZ) * (a.mZ - b.mZ)); } @@ -30,90 +48,30 @@ namespace { if(a > 0) return 1.0; - else - return -1.0; + return -1.0; } - int getClosestPoint(const ESM::Pathgrid* grid,float x,float y,float z) + int getClosestPoint(const ESM::Pathgrid* grid, float x, float y, float z) { - if(!grid) - return -1; - if(grid->mPoints.empty()) + if(!grid || grid->mPoints.empty()) return -1; - float m = distance(grid->mPoints[0],x,y,z); - int i0 = 0; + float distanceBetween = distance(grid->mPoints[0], x, y, z); + int closestIndex = 0; - for(unsigned int i = 1; i < grid->mPoints.size(); ++i) + for(unsigned int counter = 1; counter < grid->mPoints.size(); counter++) { - if(distance(grid->mPoints[i],x,y,z) < m) + if(distance(grid->mPoints[counter], x, y, z) < distanceBetween) { - m = distance(grid->mPoints[i],x,y,z); - i0 = i; + distanceBetween = distance(grid->mPoints[counter], x, y, z); + closestIndex = counter; } } - return i0; - } - - typedef boost::adjacency_list,boost::property > PathGridGraph; - typedef boost::property_map::type WeightMap; - typedef PathGridGraph::vertex_descriptor PointID; - typedef PathGridGraph::edge_descriptor PointConnectionID; - - struct found_path {}; - - /*class goalVisited : public boost::default_astar_visitor -{ -public: -goalVisited(PointID goal) : mGoal(goal) {} - -void examine_vertex(PointID u, const PathGridGraph g) -{ -if(u == mGoal) -throw found_path(); -} -private: -PointID mGoal; -}; - -class DistanceHeuristic : public boost::atasr_heuristic -{ -public: -DistanceHeuristic(const PathGridGraph & l, PointID goal) -: mGraph(l), mGoal(goal) {} - -float operator()(PointID u) -{ -const ESM::Pathgrid::Point & U = mGraph[u]; -const ESM::Pathgrid::Point & V = mGraph[mGoal]; -float dx = U.mX - V.mX; -float dy = U.mY - V.mY; -float dz = U.mZ - V.mZ; -return sqrt(dx * dx + dy * dy + dz * dz); -} -private: -const PathGridGraph & mGraph; -PointID mGoal; -};*/ - - class goalVisited : public boost::default_dijkstra_visitor - { - public: - goalVisited(PointID goal) : mGoal(goal) {} - - void examine_vertex(PointID u, const PathGridGraph g) - { - if(u == mGoal) - throw found_path(); - } - - private: - PointID mGoal; - }; + return closestIndex; + } - PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCell = 0) + PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid, float xCell = 0, float yCell = 0) { PathGridGraph graph; @@ -132,39 +90,38 @@ PointID mGoal; PointConnectionID edge; bool done; - boost::tie(edge,done) = boost::add_edge(u,v,graph); + boost::tie(edge, done) = boost::add_edge(u, v, graph); WeightMap weightmap = boost::get(boost::edge_weight, graph); - weightmap[edge] = distance(graph[u],graph[v]); + weightmap[edge] = distance(graph[u], graph[v]); } return graph; } - std::list findPath(PointID start,PointID end,PathGridGraph graph){ + std::list findPath(PointID start, PointID end, PathGridGraph graph) + { std::vector p(boost::num_vertices(graph)); std::vector d(boost::num_vertices(graph)); std::list shortest_path; - try { - boost::dijkstra_shortest_paths - ( - graph, - start, - boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))//.weight_map(boost::get(&Edge::distance, graph)) -); + try + { + boost::dijkstra_shortest_paths(graph, start, + boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))); + } - } catch(found_path fg) { - for(PointID v = end; ; v = p[v]) { + catch(found_path fg) + { + for(PointID v = end; ; v = p[v]) + { shortest_path.push_front(graph[v]); if(p[v] == v) break; } } + return shortest_path; } - - //end of helpers functions - } namespace MWMechanics @@ -181,53 +138,53 @@ namespace MWMechanics mIsPathConstructed = false; } - void PathFinder::buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint, - const ESM::Pathgrid* pathGrid,float xCell,float yCell) + void PathFinder::buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint, + const ESM::Pathgrid* pathGrid, float xCell, float yCell) { //first check if there is an obstacle - if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX,startPoint.mY,startPoint.mZ, - endPoint.mX,endPoint.mY,endPoint.mZ) ) + if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, + endPoint.mX, endPoint.mY, endPoint.mZ) ) { - int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ); - int end = getClosestPoint(pathGrid,endPoint.mX - xCell,endPoint.mY - yCell,endPoint.mZ); + int start = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ); + int end = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.mZ); if(start != -1 && end != -1) { - PathGridGraph graph = buildGraph(pathGrid,xCell,yCell); - mPath = findPath(start,end,graph); + PathGridGraph graph = buildGraph(pathGrid, xCell, yCell); + mPath = findPath(start, end, graph); } } + mPath.push_back(endPoint); mIsPathConstructed = true; } - float PathFinder::getZAngleToNext(float x,float y,float z) + float PathFinder::getZAngleToNext(float x, float y, float z) { if(mPath.empty()) - return 0; /// shouldn't happen! + return 0; // shouldn't happen! ESM::Pathgrid::Point nextPoint = *mPath.begin(); float dX = nextPoint.mX - x; float dY = nextPoint.mY - y; float h = sqrt(dX * dX + dY * dY); + return Ogre::Radian(acos(dY / h) * sgn(asin(dX / h))).valueDegrees(); } - bool PathFinder::checkIfNextPointReached(float x,float y,float z) + bool PathFinder::checkIfNextPointReached(float x, float y, float z) { if(mPath.empty()) return true; ESM::Pathgrid::Point nextPoint = *mPath.begin(); - if(distanceZCorrected(nextPoint,x,y,z) < 20) + if(distanceZCorrected(nextPoint, x, y, z) < 20) { mPath.pop_front(); - if(mPath.empty()) return true; - - nextPoint = *mPath.begin(); } + return false; } diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index dc380afb4..90c72ebcf 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -15,7 +15,8 @@ namespace MWMechanics void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint, const ESM::Pathgrid* pathGrid,float xCell = 0,float yCell = 0); - bool checkIfNextPointReached(float x,float y,float z);//returns true if the last point of the path has been reached. + bool checkIfNextPointReached(float x,float y,float z); + ///< \Returns true if the last point of the path has been reached. float getZAngleToNext(float x,float y,float z); std::list getPath(); From c0807852356af8ec06b558ebb799480da8f3d7ea Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 29 May 2013 19:26:45 -0700 Subject: [PATCH 086/213] Pathfinding Overhaul - Finished cleaning, removed unnecessary parameter in one function, fixed use of the function in ai packages and added use of clearPath() function in aiwander, fixed algorithms and got rid of excess subtractions in getDistance functions (thanks to Chris!). --- apps/openmw/mwmechanics/aiescort.cpp | 2 +- apps/openmw/mwmechanics/aitravel.cpp | 2 +- apps/openmw/mwmechanics/aiwander.cpp | 17 +++++----- apps/openmw/mwmechanics/aiwander.hpp | 2 +- apps/openmw/mwmechanics/pathfinding.cpp | 42 +++++++++++++++---------- apps/openmw/mwmechanics/pathfinding.hpp | 8 ++--- 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 5b94c4938..b873844a2 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -151,7 +151,7 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) if(distanceBetweenResult <= mMaxDist * mMaxDist) { - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; mMaxDist = 470; diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index fbae5c1d2..99df68a91 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -87,7 +87,7 @@ bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor) return true; } - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 46c5598cc..310cc3274 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -64,7 +64,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) { if(!mRepeat) { - stopWalking(actor, mPathFinder); + stopWalking(actor); return true; } else @@ -74,7 +74,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) { if(!mRepeat) { - stopWalking(actor, mPathFinder); + stopWalking(actor); return true; } else @@ -149,7 +149,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) // FIXME: This *should* pause the AiWander package instead of terminating it. if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / 2.0 - 200)) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + stopWalking(actor); return true; } } @@ -161,7 +161,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) // FIXME: This *should* pause the AiWander package instead of terminating it. if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / 2.0 - 200)) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + stopWalking(actor); return true; } } @@ -242,7 +242,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) if(mWalking) { - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; @@ -256,7 +256,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) if(distance < 1200 || mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) { - stopWalking(actor, mPathFinder); + stopWalking(actor); mMoveNow = false; mWalking = false; mChooseAction = true; @@ -272,10 +272,9 @@ int MWMechanics::AiWander::getTypeId() const return 0; } -void MWMechanics::AiWander::stopWalking(const MWWorld::Ptr& actor, PathFinder& path) +void MWMechanics::AiWander::stopWalking(const MWWorld::Ptr& actor) { - PathFinder pathClearer; - path = pathClearer; + mPathFinder.clearPath(); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; } diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index cf3820527..c82ccc215 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -22,7 +22,7 @@ namespace MWMechanics ///< 0: Wander private: - void stopWalking(const MWWorld::Ptr& actor, PathFinder& path); + void stopWalking(const MWWorld::Ptr& actor); void playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index e319116f1..3c15b050e 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -31,17 +31,26 @@ namespace float distanceZCorrected(ESM::Pathgrid::Point point, float x, float y, float z) { - return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + 0.1 * (point.mZ - z) * (point.mZ - z)); + x -= point.mX; + y -= point.mY; + z -= point.mZ; + return sqrt(x * x + y * y + 0.1 * z * z); } float distance(ESM::Pathgrid::Point point, float x, float y, float z) { - return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + (point.mZ - z) * (point.mZ - z)); + x -= point.mX; + y -= point.mY; + z -= point.mZ; + return sqrt(x * x + y * y + z * z); } float distance(ESM::Pathgrid::Point a, ESM::Pathgrid::Point b) { - return sqrt(float(a.mX - b.mX) * (a.mX - b.mX) + (a.mY - b.mY) * (a.mY - b.mY) + (a.mZ - b.mZ) * (a.mZ - b.mZ)); + float x = a.mX - b.mX; + float y = a.mY - b.mY; + float z = a.mZ - b.mZ; + return sqrt(x * x + y * y + z * z); } static float sgn(float a) @@ -75,18 +84,18 @@ namespace { PathGridGraph graph; - for(unsigned int i = 0; i < pathgrid->mPoints.size(); ++i) + for(unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++) { PointID pID = boost::add_vertex(graph); - graph[pID].mX = pathgrid->mPoints[i].mX + xCell; - graph[pID].mY = pathgrid->mPoints[i].mY + yCell; - graph[pID].mZ = pathgrid->mPoints[i].mZ; + graph[pID].mX = pathgrid->mPoints[counter].mX + xCell; + graph[pID].mY = pathgrid->mPoints[counter].mY + yCell; + graph[pID].mZ = pathgrid->mPoints[counter].mZ; } - for(unsigned int i = 0;imEdges.size();++i) + for(unsigned int counterTwo = 0; counterTwo < pathgrid->mEdges.size(); counterTwo++) { - PointID u = pathgrid->mEdges[i].mV0; - PointID v = pathgrid->mEdges[i].mV1; + PointID u = pathgrid->mEdges[counterTwo].mV0; + PointID v = pathgrid->mEdges[counterTwo].mV1; PointConnectionID edge; bool done; @@ -145,13 +154,13 @@ namespace MWMechanics if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, endPoint.mX, endPoint.mY, endPoint.mZ) ) { - int start = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ); - int end = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.mZ); + int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ); + int endNode = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.mZ); - if(start != -1 && end != -1) + if(startNode != -1 && endNode != -1) { PathGridGraph graph = buildGraph(pathGrid, xCell, yCell); - mPath = findPath(start, end, graph); + mPath = findPath(startNode, endNode, graph); } } @@ -159,10 +168,11 @@ namespace MWMechanics mIsPathConstructed = true; } - float PathFinder::getZAngleToNext(float x, float y, float z) + float PathFinder::getZAngleToNext(float x, float y) { + // This if should never be true: if(mPath.empty()) - return 0; // shouldn't happen! + return 0; ESM::Pathgrid::Point nextPoint = *mPath.begin(); float dX = nextPoint.mX - x; diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index 90c72ebcf..fcd609c8e 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -12,12 +12,12 @@ namespace MWMechanics PathFinder(); void clearPath(); - void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint, - const ESM::Pathgrid* pathGrid,float xCell = 0,float yCell = 0); + void buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint, + const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0); - bool checkIfNextPointReached(float x,float y,float z); + bool checkIfNextPointReached(float x, float y, float z); ///< \Returns true if the last point of the path has been reached. - float getZAngleToNext(float x,float y,float z); + float getZAngleToNext(float x, float y); std::list getPath(); bool isPathConstructed(); From 1d93cf09bcaff510b56313bbb14d8f31b4e14d5a Mon Sep 17 00:00:00 2001 From: graffy76 Date: Wed, 29 May 2013 21:55:19 -0500 Subject: [PATCH 087/213] Cell formatting and code optimization changes --- .../view/world/recordstatusdelegate.cpp | 36 +++++++------------ .../view/world/recordstatusdelegate.hpp | 25 ++++++++----- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp index c9dbff4f5..aa9487b70 100644 --- a/apps/opencs/view/world/recordstatusdelegate.cpp +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -1,11 +1,8 @@ #include "recordstatusdelegate.hpp" #include #include -#include #include -#include - CSVWorld::RecordStatusDelegate::RecordStatusDelegate(QUndoStack &undoStack, QObject *parent) : CommandDelegate (undoStack, parent) { @@ -16,23 +13,23 @@ CSVWorld::RecordStatusDelegate::RecordStatusDelegate(QUndoStack &undoStack, QObj //Offset values are most likely device-dependent. //Need to replace with device-independent references. - mTextTopOffset = -1; mTextLeftOffset = 3; mIconTopOffset = -3; - mIconLeftOffset = 0; - mStatusDisplay = 0; //icons and text by default + mStatusDisplay = 0; //icons and text by default. Remove when implemented as a user preference + + mFont = QApplication::font(); + mFont.setPointSize(10); + + mFontMetrics = new QFontMetrics(mFont); + + mTextAlignment.setAlignment (Qt::AlignLeft | Qt::AlignVCenter ); } void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { painter->save(); - QFont font = QApplication::font(); - font.setPointSize(10); - - QFontMetrics fm(font); - QString text = ""; QIcon *icon = 0; @@ -73,30 +70,23 @@ void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptio if (mStatusDisplay == 0 && (icon) ) { - iconRect.setRight (iconRect.left() + mIconSize); - textRect.setLeft (iconRect.right() + (mIconSize/4) * 3); - textRect.setRight (textRect.left() + fm.width(text)); + iconRect.setRight (iconRect.left() + mIconSize*2); + textRect.setLeft (iconRect.right() + mTextLeftOffset *2); } else textRect.setLeft (textRect.left() + mTextLeftOffset ); - textRect.setTop (textRect.top() + ((option.rect.height() - fm.height()) / 2) + mTextTopOffset); - - if (mStatusDisplay == 0 || mStatusDisplay == 1) - { - if (icon) + if ( (mStatusDisplay == 0 || mStatusDisplay == 1) && (icon) ) painter->drawPixmap(iconRect.center(),icon->pixmap(mIconSize, mIconSize)); - } // icon + text or text only, or force text if no icon exists for status if (mStatusDisplay == 0 || mStatusDisplay == 2 || !(icon) ) { - painter->setFont(font); - painter->drawText(textRect,text); + painter->setFont(mFont); + painter->drawText(textRect, text, mTextAlignment); } painter->restore(); - } QSize CSVWorld::RecordStatusDelegate::sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp index a2ec34822..9ab19d30e 100644 --- a/apps/opencs/view/world/recordstatusdelegate.hpp +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -2,24 +2,31 @@ #define RECORDSTATUSDELEGATE_H #include "util.hpp" +#include +#include class QIcon; +class QFont; +class QFontMetrics; namespace CSVWorld { class RecordStatusDelegate : public CommandDelegate { + QFont mFont; + QFontMetrics *mFontMetrics; - QIcon *mModifiedIcon; - QIcon *mAddedIcon; - QIcon *mDeletedIcon; - int mStatusDisplay; + QTextOption mTextAlignment; - int mIconSize; - int mIconTopOffset; - int mIconLeftOffset; - int mTextTopOffset; - int mTextLeftOffset; + QIcon *mModifiedIcon; + QIcon *mAddedIcon; + QIcon *mDeletedIcon; + + int mStatusDisplay; + + int mIconSize; + int mIconTopOffset; + int mTextLeftOffset; public: explicit RecordStatusDelegate(QUndoStack& undoStack, QObject *parent = 0); From 73a967174267891896e03d9ddc3c369bc3e81961 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 29 May 2013 20:05:17 -0700 Subject: [PATCH 088/213] Pathfinding Overhaul - Changed the name of checkIfNextPointReached to a more intuitive name considering what it does (checkPathCompleted) and fixed a minor bug in it, modified buildPath() to take one final parameter, a bool which dictates whether or not to always use pathfinding (like AIWander should be doing) or to allow for "shortcuts", modified all ai packages to work with these two changes. --- apps/openmw/mwmechanics/aiescort.cpp | 4 ++-- apps/openmw/mwmechanics/aitravel.cpp | 4 ++-- apps/openmw/mwmechanics/aiwander.cpp | 4 ++-- apps/openmw/mwmechanics/pathfinding.cpp | 24 ++++++++++++++++-------- apps/openmw/mwmechanics/pathfinding.hpp | 4 ++-- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index b873844a2..755994622 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -129,10 +129,10 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) start.mY = pos.pos[1]; start.mZ = pos.pos[2]; - mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell); + mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, 1); } - if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) + if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) { MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; return true; diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index 99df68a91..4307ed284 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -78,10 +78,10 @@ bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor) start.mY = pos.pos[1]; start.mZ = pos.pos[2]; - mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell); + mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, 1); } - if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) + if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) { MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; return true; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 310cc3274..b7d391a9f 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -235,7 +235,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) start.mY = pos.pos[1]; start.mZ = pos.pos[2]; - mPathFinder.buildPath(start,dest,mPathgrid,mXCell,mYCell); + mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, 0); mWalking = true; } } @@ -254,7 +254,7 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) actorPos[1] = actorPos[1] - mYCell; float distance = actorPos.squaredDistance(destNodePos); - if(distance < 1200 || mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) + if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) { stopWalking(actor); mMoveNow = false; diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 3c15b050e..78be90804 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -148,11 +148,16 @@ namespace MWMechanics } void PathFinder::buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint, - const ESM::Pathgrid* pathGrid, float xCell, float yCell) + const ESM::Pathgrid* pathGrid, float xCell, float yCell, bool allowShortcuts) { + if(allowShortcuts) + { + if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, endPoint.mX, endPoint.mY, + endPoint.mZ)) + allowShortcuts = false; + } //first check if there is an obstacle - if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX, startPoint.mY, startPoint.mZ, - endPoint.mX, endPoint.mY, endPoint.mZ) ) + if(!allowShortcuts) { int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ); int endNode = getClosestPoint(pathGrid, endPoint.mX - xCell, endPoint.mY - yCell, endPoint.mZ); @@ -175,14 +180,14 @@ namespace MWMechanics return 0; ESM::Pathgrid::Point nextPoint = *mPath.begin(); - float dX = nextPoint.mX - x; - float dY = nextPoint.mY - y; - float h = sqrt(dX * dX + dY * dY); + float directionX = nextPoint.mX - x; + float directionY = nextPoint.mY - y; + float directionResult = sqrt(directionX * directionX + directionY * directionY); - return Ogre::Radian(acos(dY / h) * sgn(asin(dX / h))).valueDegrees(); + return Ogre::Radian(acos(directionY / directionResult) * sgn(asin(directionX / directionResult))).valueDegrees(); } - bool PathFinder::checkIfNextPointReached(float x, float y, float z) + bool PathFinder::checkPathCompleted(float x, float y, float z) { if(mPath.empty()) return true; @@ -192,7 +197,10 @@ namespace MWMechanics { mPath.pop_front(); if(mPath.empty()) + { + mIsPathConstructed = false; return true; + } } return false; diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index fcd609c8e..1727c650f 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -13,9 +13,9 @@ namespace MWMechanics void clearPath(); void buildPath(ESM::Pathgrid::Point startPoint, ESM::Pathgrid::Point endPoint, - const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0); + const ESM::Pathgrid* pathGrid, float xCell = 0, float yCell = 0, bool allowShortcuts = 1); - bool checkIfNextPointReached(float x, float y, float z); + bool checkPathCompleted(float x, float y, float z); ///< \Returns true if the last point of the path has been reached. float getZAngleToNext(float x, float y); From e403773e95f5c0ebd85e5c69b15731376e6b90fa Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 30 May 2013 13:33:49 +0200 Subject: [PATCH 089/213] Simply removed background from status icons. --- files/opencs/raster/added.png | Bin 1223 -> 840 bytes files/opencs/raster/modified.png | Bin 1855 -> 2022 bytes files/opencs/raster/removed.png | Bin 1490 -> 1311 bytes files/opencs/scalable/status/added.png | Bin 0 -> 840 bytes files/opencs/scalable/status/added.svg | 45 ++++------------------ files/opencs/scalable/status/modified.png | Bin 0 -> 2022 bytes files/opencs/scalable/status/modified.svg | 29 -------------- files/opencs/scalable/status/removed.png | Bin 0 -> 1311 bytes files/opencs/scalable/status/removed.svg | 36 +++-------------- 9 files changed, 13 insertions(+), 97 deletions(-) create mode 100644 files/opencs/scalable/status/added.png create mode 100644 files/opencs/scalable/status/modified.png create mode 100644 files/opencs/scalable/status/removed.png diff --git a/files/opencs/raster/added.png b/files/opencs/raster/added.png index 456966a9c953555eb33677f2c6ad507b01b58529..091e3c61a60c0c0d403f2ae1f900c88ed0cf1521 100644 GIT binary patch delta 816 zcmV-01JC@&3CIRUiBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hX4Qo1am@3 zR0s$N2z&@+hyVZp32;bRa{vGh*8l(w*8xH(n|PC!1Sfw2#Ysd#RA_$K;OffNJ9fl0B4CVD zj6-1}RY`wbN`4VnQR8y@p2H~~;}Aofl!)l$1|%vh;X2;M`?!|b$0K}=Z}1b2#Zk%P zJOW-t51*l1*w0&dfS<+D$fi^Pao(?@Ti3O%t*xx!&CN{*2M5>iCcZDuB7~6L#QEOE zCkSh6Yay5Q_4Oc5ncL#@TP(?Cp;-A#LMxzYS^4Pl!n@O9+#K8R*Kfu%! z#uR1}5GKBpXE~OYnUowlRBA^!xpZ0lb%T zUcT_R(N;jyv;vx@70@)TfTn2$G)*OXp>=HGR;iiW+1bg8+1S{yyStkelgu1(J@q#3 zcSH~VC+_0LU@+*Wi~d*k_xJ7X?G=UMD=~lPaR(| z<|}Ca!mpx;0Zt|(@Q1j>{ZL*>$@vBRD2h0gQBsQ4*|-xz2so*#>R4Rjp0}u{a7p|h zJQnu~9;M`F@qAG~JsVHVwZV{959TSt=V7|l6hfFsz;j&q+h{AGX<7kI(+X&s^K4+V z2JvZVI2_vE-p&d>Iy#yhjudQgKg*(go3+M!_$4J!(hl(fURSuyS~>y&PefC7M_gB} uGy6Eem*Ot{6NRI2;a~PB62Qyzy3OAq4O5KW_#Zd`0000!lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D(<+r!7#%P+tuAjnTgR~zU^H8nLI9W7sfA6q+Xdq+DLS0^_Q7f&yD{{SB! zUr%KfB~ek)r%#_sNl7UxD|q{Q+Sppz+1q+~yDKRvNk~Zi|Nmc3PEJu#-rB|z=n;2M zS1%tAMJ1s1a+X%+);3o54t8?#axQL8<`!lSj`mJ2jzBNFx;s0$ILOJ%%F4<(Iy;z} znOIp{+SpnH!$DR~Mp{PN$k@=>#K^?d$jsct+``n#+QP!pOiD^pLQ-5`Ur$q0Lql8c)Q2qYxLWn`qZwY9{=#q{*_OiWC~CB)S=)cN`O)YMe@`1q8SmH7C0 z6%^!oczA#ob8~Y`OG|Nba*B$IaBy%434tPjg@r{xKtM=Hh@G9Cjg74;gmninj5tby z{DO7w|GoeB?|t0`H|1vn#Tb*k-CcBc-7Q=VvL>2>6&TkNA4N5OK$N4p$&#d4yc`JapLjb($+eiOJ6f?2P<3F(sRG(O#U?g z+mFI`KbGx%_x+vC^WA$Z?B+9HxR9|;Aos0oSoZR>_paW(o4UO;YJSO$I0Wq@uT64 zCzDl<`f^@AQ_W*%aQTpk`$W$=p(7&p%`P_%?KJ%H`&Yvb$-H|Q=cZyh-=xJQ&yWCe8=nQCkc_FmAZw+ z$+oj&o0DEv?~GZI^PJn>V8yjhx2HPo+!L&I=v|z`q#f^{Gyho1tJHXZ_lA0b9=|_} zGd?89^QkH;$R4`5QP9G!X>zb~K^0T_bGHY7c=T4eEvRBNy~%OHbVo=}LlI|q=wjEC z;S0PrEz&T0CAI$7uXi=((?SBST6u;3U%|yze=%^j@`BKMo>#wq)HDBhXv3y!HR0ps z$)y*V)b4tn>J__n-dQcf^kMyrm-lB!j}VJsDux!5|5;Aviy+ pq&%@Gm7%=6TrV>(yEr+qAXP8FD1G)j8!4b722WQ%mvv4FO#p%Rp2PqE diff --git a/files/opencs/raster/modified.png b/files/opencs/raster/modified.png index ca613f9e48f89cd597f9a1296a7b6cd921cb19eb..0ac732ad9183c74307ee3c0d6401631e1cf962ac 100644 GIT binary patch delta 2008 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 II;Vst04OK`B>(^b diff --git a/files/opencs/scalable/status/added.png b/files/opencs/scalable/status/added.png new file mode 100644 index 0000000000000000000000000000000000000000..091e3c61a60c0c0d403f2ae1f900c88ed0cf1521 GIT binary patch literal 840 zcmV-O1GoH%P)w#0K~!jg?b>^-{Q;b7lB2`ITN`4VnQR8y@p2H~~;}Aof zl!)l$1|%vh;X2;M`?!|b$0K}=Z}1b2#Zk%PJOW-t51*l1*w0&dfS<+D$fi^Pao(?@ zTi3O%t*xx!&CN{*2M5>iCcZDuB7~6L#QEOECkSh6Yay5Q_4Oc5ncL#@TP(?Cp;-A# zLMxzYS^-Vd3TT??gDm-*Nt?yQ!2K6Lz|<7R6lM|-Ccde2#+WVPm2^C-rvYo$#P1z( z8r8UoPelNC zY~fa^ncLaf$%@(7*s#01n-!DH9C1DMHtu&s5B?|a;>KVw=%$PQSN8Y!?d|Oqh2kqQ z=Wz!o7~orcEY<@{Gdek2(0o*q#TmZ959TXq{=%=KhyhL}Bk+f~#QjiSNy+&I{3wbz zlu=TO)!DccLI^mis_Ix=;-0str*KL9A3PTK3Ld58X7PMcKRp{y%(cOgRuASW!slVS z)f7UQN5FGj_}geJplMnGP16c!n)7V42JvZVI2_vE-p&d>Iy#yhjudQgKg*(go3+M! z_$4J!(hl(fURSuyS~>y&PefC7M_gB}Gy6Eem*Ot{6NRI2;a~PB62Qyzy3OAq4O5KW S_#Zd`0000 - - - - - - - - - - - + - zCAcCHS*xf4V-uEySWUDsq9lYr2r)5Wf(G>uW17V@7}$-3tO>!eyVkA9AB~`k*IsS3(9fsP@ywV4Fl9#^Mx%Zy$IrrT2>pdePgiXd61NcA`FhClZk;lL+ z683_YJfH&j08kG69vBB^!e;ci1c(C5fo}t4z}J8YV@x*eT?kzOV~o>&3-EDtH`W8U zQBw+4058nNEJcAjV2{1`?R}kn4wXU`z-m7ZJPT~f`zZx90p)f~XcYDi_`nii7Z7i0 zX`!X11)v1@0#HlXW-B70T&TNz26zs*14vI#kM#8P2x|9Zz{l(u6B^$T1&9C*zz+aP zBodNNrzM?EOCphQLi`X|2}Hu;8;S|pz*PbyfzJSRb#)PqMu|qFbai#Pp`Qj4K&hRx zcnV4TKI-?s14u?10r|%nGmzptG}+>gwv;nCj|k zIy*bv<1U~ch=sBXA!y%2ef*2SjPLt0G&Cf$X=rFjeBT!|op{mC@t*1-Mmd)>7=lz*l3?x%r_F=htH7@)=isRQ1H2BYP`QVaGSR_m2kJ9DN2jg5^A4i4gZ zg&kWqo29wAnHx85%r|5TxQEsc{{lvVe*$mi2|8-8zej*(;3YId`USZI@pzm>B0(~l zB$-U+?o+8$QSbns=W+Vg39mD^DA{3=9lNeSN(H ze+SrS6r_E?ttUswxM51o$HAXiBlJbaotwqVDl| z;2I#YSWJ3*d!IP?GiT07NlA$VKZs_s%b69u=ZdthrhN{06A;hy+PYnFYlPAUV zJO};{Xmenx#r9C7o-bvHpl+-k__bX~4jw%C*uftV>r*49QC z6`}9@w6?ao#~I6G%JM8q3#o}+uxkX^xN+kGrWU3R8#cJxCd(tRW)>oVGozL8*aTQ@ zc?8B4XrS#LM9_+9=`5y;ro6S5Sssy~9gCon8Z>!&4-iczlhoJOFBIpz)Y#bQ+AyW4 zi3T>KpaOVkto4!H5Z1>Ot90$~d%KpEQOzYWO6ix=kvaryFP zNu^Txxy%^wZ}+@q%NDtI?b@7k&z?P-pEiFOC=Epb9<GXpQkf;9J;=50K{OW;uWU zyoiWw-@e_g)kDDd2ti)=xB%7!>M>HO6#f1E?)SHWp8>A`f3tR<26C@djWKDop1p_m zcz%a=slPNhI9R=H+cvgt-O7?BxlYQv2^!D>>_8kXD(>WI+u8Xq&}yjxO~4`)uv_#z zMJ%}0z$bxUVf(6i*KO2klr3rpY&49b-8t6~nn7LNkAOb{{{a32WSqteC`(XBaL1AhXx z0DFN|=&rtL`987$pc=mmd>ysjx0u7uAB99DYmAxV!TGoi{04oSnI^!u6{ZmXJQFHK zcfxgwL;vz5?+X{#&d;Fdte|NY6d-S5msm;Iz!%H!zYAf)#yFq2ng9R*07*qoM6N<$ Eg5avTxBvhE literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/status/modified.svg b/files/opencs/scalable/status/modified.svg index 72458efda..552509a32 100644 --- a/files/opencs/scalable/status/modified.svg +++ b/files/opencs/scalable/status/modified.svg @@ -1096,35 +1096,6 @@ - - - - - - - - - - - pLLP)?J#lKJ(!*lTkefSmXYRG*rV=Aru_F82_c`a>k8`dg z5h3)6q9_88dA{thH?OTI^m|bhtpHc_^%8g`BCqBeJaxpX+WH50843~v5Jk}yU=4T& zr~{|KGvMz~2z5jacw7HYfeG*;#FjUJioXVY0Bixbfn(rD;1^)#JFtph2i^yoYV&8{ zC*U_=>J1?xl`ql|uLF00N5FGHfTzGvMXUoW9=2A14RydC@Q2#^9XL?uZ1~s`k!k=H zUkA2PH{FaJL0BN;aG8&C!XJ^N>b)XK}K+`-Jz)G7VQ~Yc;6A_UlNoAHp%MxfgsOUK+NK_2ZZ!` zy`H@hM5k!p@IfUCew zU{@(GWZ)!87Pc`SkEPXWW#UJ`7r=YKsu&T7baLF%Jeyt=#G>Nc?Y6x<-zGi1p3MO{ zztuN^hnEdeApSna1}TnxAlver8i|w3fS61s(&=>UJ!Q)lp98QUwscazR)_-e_bEFh z+W(MCjKpLzk#4tZir*_rn@Rx5M`Gy^1>zr+dA<@r&Q_;vVlOS7k|dE{uV?3cspq`_ z42VtAgW0#}(cq#W3XUG%0r&8%$W{n@qQK8D^7wTdD!gwNBTG#o>lC|3x~bNfH-!xG zS@$4WhWHAI!nMB=!1DZX+2Tte_NySOJpbCnJ0PZ2ktkdHm!38O5c@d#PDN|}x$ePb z9p)Smxk#Ae*LCJ!n&&+r4h)EMCFNDpGHsW%Xn11^8Vll?YP^9}&}1d$A#Y$w8OO2N zi+!kCuVIvwSy8_W{KW+q^@~8vW-}QK2AQp=s_`aPQJ=L{wt>g!dFLYAD)T^C;!oB4 zS;sF|Qf7^!8m^q6!@7t%gzY2U^JBD-dNZsff8HEZZaca8K?x=Fg79|J!CzY>1Y-Qet^ z`$N);?qkx6?h|iYz5oWq8t|^dEc#P}I_WZ7=j^8jry;ifUqAM+1}1c{GJEsd`WF}% Vg={u)iKhSn002ovPDHLkV1o2`SGE8E literal 0 HcmV?d00001 diff --git a/files/opencs/scalable/status/removed.svg b/files/opencs/scalable/status/removed.svg index e1ed58ad3..9e5a27f82 100644 --- a/files/opencs/scalable/status/removed.svg +++ b/files/opencs/scalable/status/removed.svg @@ -23,11 +23,11 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="2.8284271" - inkscape:cx="-48.002913" - inkscape:cy="11.790793" + inkscape:zoom="5.6568542" + inkscape:cx="5.8735623" + inkscape:cy="23.288227" inkscape:document-units="px" - inkscape:current-layer="layer1" + inkscape:current-layer="g6138" showgrid="false" showguides="true" inkscape:guide-bbox="true" @@ -913,33 +913,7 @@ inkscape:label="Livello 1"> - - - - - - - - - - + transform="translate(3.5529905,1004.1857)" /> Date: Fri, 31 May 2013 04:08:44 +0200 Subject: [PATCH 090/213] Fix being able to move slowly when over encumbered --- apps/openmw/mwmechanics/character.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c7aeb1b5f..aa20e1414 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -461,15 +461,18 @@ void CharacterController::update(float duration, Movement &movement) Ogre::Vector3 moved = mAnimation->runAnimation(duration); // Ensure we're moving in generally the right direction - if((movement.mPosition[0] < 0.0f && movement.mPosition[0] < moved.x*2.0f) || - (movement.mPosition[0] > 0.0f && movement.mPosition[0] > moved.x*2.0f)) - moved.x = movement.mPosition[0]; - if((movement.mPosition[1] < 0.0f && movement.mPosition[1] < moved.y*2.0f) || - (movement.mPosition[1] > 0.0f && movement.mPosition[1] > moved.y*2.0f)) - moved.y = movement.mPosition[1]; - if((movement.mPosition[2] < 0.0f && movement.mPosition[2] < moved.z*2.0f) || - (movement.mPosition[2] > 0.0f && movement.mPosition[2] > moved.z*2.0f)) - moved.z = movement.mPosition[2]; + if (speed > 0.f) + { + if((movement.mPosition[0] < 0.0f && movement.mPosition[0] < moved.x*2.0f) || + (movement.mPosition[0] > 0.0f && movement.mPosition[0] > moved.x*2.0f)) + moved.x = movement.mPosition[0]; + if((movement.mPosition[1] < 0.0f && movement.mPosition[1] < moved.y*2.0f) || + (movement.mPosition[1] > 0.0f && movement.mPosition[1] > moved.y*2.0f)) + moved.y = movement.mPosition[1]; + if((movement.mPosition[2] < 0.0f && movement.mPosition[2] < moved.z*2.0f) || + (movement.mPosition[2] > 0.0f && movement.mPosition[2] > moved.z*2.0f)) + moved.z = movement.mPosition[2]; + } movement.mPosition[0] = moved.x; movement.mPosition[1] = moved.y; From 09ab541102baa459f30cbe9c9983905a22cb1afb Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 31 May 2013 11:50:03 +0200 Subject: [PATCH 091/213] Colored status icons. Hopefully everybody loves watercolors! --- files/opencs/raster/added.png | Bin 840 -> 862 bytes files/opencs/raster/modified.png | Bin 2022 -> 2149 bytes files/opencs/raster/removed.png | Bin 1311 -> 1772 bytes files/opencs/scalable/status/added.svg | 8 ++++---- files/opencs/scalable/status/modified.svg | 8 ++++---- files/opencs/scalable/status/removed.svg | 10 +++++----- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/files/opencs/raster/added.png b/files/opencs/raster/added.png index 091e3c61a60c0c0d403f2ae1f900c88ed0cf1521..aff7e25d460be771eb1c93bf556bedce44a06f0f 100644 GIT binary patch delta 764 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 delta 1934 zcmV;92XXl25ath%ZhvD*L_t(&fz6tKY*bkl$3OSInQ1$1x2@DdnZW{ETKrim1)Egjh|qF`^`dKL{}~V1fqq4`Z6eG#J>8gscg{u)Ef+$RCZMrh$}b z%ZhGEtzc=V(>eZe?j45O&b-nGc#@aC*SYte?>YC}^Xok$B7cNU#ux+mKol@Q8kmvC zz$_B>f|fj>0{8$>4*VV%2WG-%^tc3w0?UDK17*P1fC*zvHtbypT>xW@(|!x^adbD< z1GiCA3RM6v%*8B4fjVH1z4z^XoqZ0KLKVPjKMp(#Y|8s71vCNWc1&m#_73>K5?~h) zZ)s_vrKJU+1b_GfP)pcmDsJnaycn-J&NKa3X^z`%yYWHKn$Ltsr8s88FhyV@1 z4**Fd5|U1*C7n)7B9U-H{18|PM8e`5iV4}kRRSb|&j56FbrFq5iAJMzb#=L+p9T^@ zshzWU3Q7Au>i53`NJT}3jE#+nqp`6usi>%MyKvA7;eY>M?10r|%nGmzptG}+>gwv; znCj|kIy*bv<1U~ch=sBXA!y%2ef*2SjPLt0G&Cf$X=rFjeBT!|op{mC@t*1-Mm_5qsUWJCuK=^X{jCj4@^g$QYo;0)MFk-h~FE<-k%4_8nI1l~y}*rUH$P zjSLPB;(3J~TQ-}exw)AeH*U-~WD2;4)(`&zMuC3$$0G{V@`t)h~`uZ3d8OdG4!^7OVb&IK~DYw&03M?~;?%Y=l zs(wfqYVQ^X5%ivu2Gu{C9zG0*&Zl&-wC|z?ad=N$TqAr_E?ttUswxM51o$HAXiBlJ zbaotwqVDl|;2I#YSWJ3*d!IP?GiT07NlA$VKZs_s%b69u=ZdthrhN{06A;hy+ zPYnFYlPAUVJO};{Xmenx#r9C7o-bvHpl+-k__bX~4jw%C*uft_ zC)TVo&`<=AF>$ctsRObZ$27@TY;Yd z89;XI*dh1t-wzG^>L@B6g2wz|g|%VWy&EJ_QhiCwU31lYK7;{v7@rVSf5xZ5VnBd}%` zB7ifamGIaESZ#R(#uaFw?H)wXifQRAri-S$wU${Pk)R!mppqIid3p~JO@Ahn)YsQ9 z6z9Cu*x2aWFr}!81~#Lh0(fYx&6^!HOA1^*5)2tEw5nM z0=m%{8V4=|a`foYg08W*w^te(8geN?Q&W?iJ9n<&oC60AxbeRQ-V4M6VGAfg8QSB& z4amid7v}_V`SN8+rBeC1%zqg0Z}+@q%NDtI?b@7k&z?P-pEiFOC=Epb9<SFbiWT|h@)w{BeYsbQdJ@lGC1{QD zLEu~1iVu+H=4Ls6{=A5YY~Q}!t<^)o_Xt5=_qYJo1nMzTsTBSF{qFa-fu8}d0DrS~ zp9XTTRE;rdw4S|(_J4SOhjyvIG&nd|y=~hzwr<_Zk|nuL%DV{~&;sm094#vDKLY;% z{sUy3#tSG*P)Bgjf*wN~RA UIG?zh00000Ne4wvM6N<$f?qPK6#xJL diff --git a/files/opencs/raster/removed.png b/files/opencs/raster/removed.png index d4b0a4897eb11d650f2215bdc9fea6cacb45c840..2ca9e094be380f7d6da1f5c34897f03a4146dfff 100644 GIT binary patch delta 1683 zcmV;E25kAC3hWJ#ZGQ%7Nkl9(E6vuyW+Va|&sfs`hO48{B8>gU41?@&O zQVqde=6rqD?6N-&AYH31ubuG$=lnrr#AMDX0nt_5v1&K;$hCZD3y14gF zUtiyQ^WIEb7T%<3I-NQ9|2y}*d(S;*3?T$zhhZ27fGFp~9)I@AwPl3;oM9Ldpi2D| zfN3GbbXk*2M^r0YQ$QgsNGJfqFsc9(SO!FaJn$!Ag@sU#r~@8RzjMG{;9eM8fdQ2G zTA%?)0Z##!fggbDz+}*gmG~I&1kkK(W`Li7aUd5MLI_dv2f4&CU@htiG=v)@L?hP z`$g`^5jTjEE8+SO+aA~i@EULcsBKN9_@ccXv%0$Y-mGP@X>gDWnGDEXsT(+rda%{o zV!$e3i?S78mq>7~vy+EvYm2t>_wTdy_;Jo(xuR_yRJLy5@nFvZu!(O};`e)r_khSL zk!RJ!Re!)rCB7SouTLZxafmMgaSHg=4Pq96ZJ%!hwgK;!67K_%2EIlfP%kT}`1(YG zb6s83o2I8N7l<@+CFVdB0hIVUI*`{8 zh7dv@EIQ`56Tf4WT#398LVrZmdn3S7)kW7Xa4-j3lgi||qu%W35 zXz_N4&)V9ktEmB4p)}S35ksZ17>2O~cno+JI0md}NhUel(Lub-i9v>w1}b;lot)&A zfqwxmj*Wp#H{Jj)0=I+^1-%0Q0)GLQfFnTuLMFqe!NH=4az@-VD;B@;*fA|W2Yd*O zDy>tXLP+J{dEh2+1~@cd5S5Dm{@OJyen0RPau>3M?T80JZA&@i6Mho;#OEFa#Drzh zI$L}i7{MiNkJvw`{*gsOoJQ`wiwZGeS$}LC7~s3voLWD!xxR zAaupZk@yRl43(xGR-r)K@UZ^;E#PNlnRCism6%3e(=G!?0c&J*lx;&pp?@J<$|_~& zPFA77wxJ@{S6t<26A5%sa>mvRGWMOL@RTBdD z(qbKQ&wU+PQa39sElvY3A!ghz2#-(jne+p{k2 z`a*bk{sbNsYQOS&pp|eD-+ztm4vS2S>zRGJyF$2#e;@b~7ta?*i3Ud;cm^2`llV6{ zvdA-JPOFKT21hfpJeUPUOEM`YdV7WF?-!GOeWEp$(zf!*UYzdIc(<(rw3y<+)5x$W zLO5DXSzsr!w(8en(hz&qYKfL)Qrzz8af;uE?DUlElLc+^X^7%V*ngUQ+Vd%==L0}w z9k%i+T$|PVDr@q2gi|-Nxh;?f%T9cndjTMHoAr(gn?RoT?UA_+M+2l8XhI%*mnc#C zaIvM+cHQVsARFD6k^8*+1M6lhD1Z&Z1ePn9O229l1s+zv^;Zq@VQl@szU<+cn6Q)i d*(=x9e_}t^l63U9)C>Rs002ovPDHLkV1n$@5NrSd delta 1218 zcmV;z1U>ug4W9~-ZGQxuNklY}j6o#KkLsL6Wg9IyR1siDNluA@c{#<3{ zC6Hgz#z{&e(JuM;dmx1k3lN4ft&lx&YNXP`V$P78J9B65wd1A|BU!N```q_A=iHBT zt|Jj4^ogP<0+4yW?65blttj++Q53BJSM>D~cqJmQ<{CV8#DA*V`UiL!3K9emMbQ;t z4R{Br1E;_<;O|ffbwmw#TmMdh3GgDsmN$TkzXp5&Yyr1{W8g>N7hvW)u!>&?-Upg$ z^Jm~E;5T6E4Iv_xFVYaN19yN&z;i%=r@&A}tOF|^wpM@*b-*6*huZobI8f(o_}CJW zY5)~q2eyGD;C}@mjYdOs;3;sZ5cRTwRs3}oxd$YG)M_=;)_w?tujjXcuQKt2!9e0T zmVUo)4!oxW7e>PH{FaJL0BN;aG8&C!XJ^N>b)XK}K+`-Jz)G7VQ~Yc;6A_UlNokF6 zPJjn0xB+Y`&@dC<>2z}9D3ayH58`hg(NS3u146(qg{VjsArDIS>stE9W)mq0wP zcn5^^dVjrO@eYVTfzN>(z*{E38t}1B7-=*b636je1KJS%eqWL#S;*FCG%`24A@GrE zjxvC&z)fIRDKBK;BuN&wF&>Yl)oNwpN5B`rd%&s~5r}kh+|oRoUKGTl;@j=Ey*%G0 zJ-wdI0Xe_bH-U$j4N)NeKE?(qj(s58@|zlolYh&Am`o

2&NpWy=d zsejg(H-!xGS@$4WhWHAI!nMB=!1DZX+2Tte_NySOJpbCnJ0PZ2ktkdHm!38O5c@d# zPDN|}x$ePb9p)Smxk#Ae*LCJ!n&&+r4h)EMCFNDpGHsW%Xn11^8Vll?YP^9}&}1d$ zA#Y$w8OO2Ni+!kCuVIvwSy8_W{KW+q^?!>%%w{tg3gNLR#Bg|Rknf0=y~TN z+bZ)wSmICB`&q{?S5jt;txtfj=YgndY=uA+h(A&XU(c;V1rT>aBT>>?yhmU?;qZJ; zd=9{X*Z}VOLO7bcSsQSZfTGCZd1r^(br$lDgyRrqw$~#(%hLk!k6fNF1+XCQ0)J16 zAROXzTRt8&wnKdB-9RaT1(BQB))kZ4w<)_~${-Fg`c82iyC!U9RpwJtnh^g*!q`~+ z&+d7M6U){qX=}e(mNr2E1?lvdbW0b~K5A*-#sea|W_@nty!SP0=tXyp^isM>x}6^b zKLEcHe$n0F?4tWa(u?k6(u?jBZ#!GQ00zVw@UFrv`cs2C=`vgA?575&A-4WsKlZQ& gCUmeed-K}*7Z?|XY&LO;rvLx|07*qoM6N<$f~;dj3jhEB diff --git a/files/opencs/scalable/status/added.svg b/files/opencs/scalable/status/added.svg index 207e1aee3..d83649f50 100644 --- a/files/opencs/scalable/status/added.svg +++ b/files/opencs/scalable/status/added.svg @@ -23,9 +23,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="2.8284271" - inkscape:cx="-7.6178573" - inkscape:cy="-1.6044289" + inkscape:zoom="5.6568542" + inkscape:cx="-3.0608173" + inkscape:cy="3.614868" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" @@ -923,7 +923,7 @@ inkscape:connector-curvature="0" transform="matrix(0.01709132,0,0,0.01709132,42.964466,990.51997)" /> Date: Fri, 31 May 2013 17:01:42 -0700 Subject: [PATCH 092/213] Pathfinding Overhaul - Fixed selecting cells that are inaccessable from AIWander and pathfinding in general (sadly requires minor effort on the AI Packages implementation but it is the quickest way I can see), minor cleanup again (there is a lot to cleanup, this will prolly be in every commit). --- apps/openmw/mwmechanics/aiwander.cpp | 25 ++++++++++++++++--------- apps/openmw/mwmechanics/pathfinding.cpp | 20 ++++++++++++++++---- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index b7d391a9f..1530804cd 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -219,12 +219,6 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size()); Ogre::Vector3 destNodePos(mAllowedNodes[randNode].mX, mAllowedNodes[randNode].mY, mAllowedNodes[randNode].mZ); - // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): - ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; - mAllowedNodes.erase(mAllowedNodes.begin() + randNode); - mAllowedNodes.push_back(mCurrentNode); - mCurrentNode = temp; - ESM::Pathgrid::Point dest; dest.mX = destNodePos[0] + mXCell; dest.mY = destNodePos[1] + mYCell; @@ -236,7 +230,21 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) start.mZ = pos.pos[2]; mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, 0); - mWalking = true; + + if(mPathFinder.isPathConstructed()) + { + // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): + ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; + mAllowedNodes.erase(mAllowedNodes.begin() + randNode); + mAllowedNodes.push_back(mCurrentNode); + mCurrentNode = temp; + + mMoveNow = false; + mWalking = true; + } + // Choose a different node and delete this one from possible nodes because it is uncreachable: + else + mAllowedNodes.erase(mAllowedNodes.begin() + randNode); } } @@ -254,14 +262,13 @@ bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) actorPos[1] = actorPos[1] - mYCell; float distance = actorPos.squaredDistance(destNodePos); - if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) + if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) { stopWalking(actor); mMoveNow = false; mWalking = false; mChooseAction = true; } - } return false; diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 78be90804..d3a44e0f9 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -156,7 +156,7 @@ namespace MWMechanics endPoint.mZ)) allowShortcuts = false; } - //first check if there is an obstacle + if(!allowShortcuts) { int startNode = getClosestPoint(pathGrid, startPoint.mX - xCell, startPoint.mY - yCell,startPoint.mZ); @@ -166,16 +166,28 @@ namespace MWMechanics { PathGridGraph graph = buildGraph(pathGrid, xCell, yCell); mPath = findPath(startNode, endNode, graph); + + if(!mPath.empty()) + { + mPath.push_back(endPoint); + mIsPathConstructed = true; + } } } + else + { + mPath.push_back(endPoint); + mIsPathConstructed = true; + } - mPath.push_back(endPoint); - mIsPathConstructed = true; + if(mPath.empty()) + mIsPathConstructed = false; } float PathFinder::getZAngleToNext(float x, float y) { - // This if should never be true: + // This should never happen (programmers should have an if statement checking mIsPathConstructed that prevents this call + // if otherwise). if(mPath.empty()) return 0; From 09beafd044f822bf8af9570225d3ac1419762a2a Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Fri, 31 May 2013 17:49:52 -0700 Subject: [PATCH 093/213] Pathfinding Overhaul - Master cleanup! Cleaned pathfinding entirely, all AI packages that are implemented as well, Increased buffer! This makes the intro guard no longer walk into you or go to far into the room (not tested against vanilla distances but it seems accurate enough until the next itteration of pathfinding fixes). --- apps/openmw/mwmechanics/aiescort.cpp | 238 +++++------ apps/openmw/mwmechanics/aitravel.cpp | 135 ++++--- apps/openmw/mwmechanics/aiwander.cpp | 508 ++++++++++++------------ apps/openmw/mwmechanics/pathfinding.cpp | 2 +- 4 files changed, 452 insertions(+), 431 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 755994622..6af87e8bd 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -13,8 +13,9 @@ namespace { float sgn(float a) { - if(a > 0) return 1.0; - else return -1.0; + if(a > 0) + return 1.0; + return -1.0; } } @@ -24,151 +25,156 @@ namespace TODO: Take account for actors being in different cells. */ -MWMechanics::AiEscort::AiEscort(const std::string &actorId,int duration, float x, float y, float z) -: mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration) +namespace MWMechanics { - mMaxDist = 470; + AiEscort::AiEscort(const std::string &actorId, int duration, float x, float y, float z) + : mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration) + { + mMaxDist = 470; - // The CS Help File states that if a duration is givin, the AI package will run for that long - // BUT if a location is givin, it "trumps" the duration so it will simply escort to that location. - if(mX != 0 || mY != 0 || mZ != 0) - mDuration = 0; + // The CS Help File states that if a duration is givin, the AI package will run for that long + // BUT if a location is givin, it "trumps" the duration so it will simply escort to that location. + if(mX != 0 || mY != 0 || mZ != 0) + mDuration = 0; - else - { - MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp(); - mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100); + else + { + MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100); + } } -} -MWMechanics::AiEscort::AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z) -: mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration) -{ - mMaxDist = 470; + AiEscort::AiEscort(const std::string &actorId, const std::string &cellId,int duration, float x, float y, float z) + : mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration) + { + mMaxDist = 470; - // The CS Help File states that if a duration is givin, the AI package will run for that long - // BUT if a location is givin, it "trumps" the duration so it will simply escort to that location. - if(mX != 0 || mY != 0 || mZ != 0) - mDuration = 0; + // The CS Help File states that if a duration is givin, the AI package will run for that long + // BUT if a location is givin, it "trumps" the duration so it will simply escort to that location. + if(mX != 0 || mY != 0 || mZ != 0) + mDuration = 0; - else - { - MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp(); - mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100); + else + { + MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100); + } } -} -MWMechanics::AiEscort *MWMechanics::AiEscort::clone() const -{ - return new AiEscort(*this); -} - -bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) -{ - // If AiEscort has ran for as long or longer then the duration specified - // and the duration is not infinite, the package is complete. - if(mDuration != 0) + AiEscort *MWMechanics::AiEscort::clone() const { - MWWorld::TimeStamp current = MWBase::Environment::get().getWorld()->getTimeStamp(); - unsigned int currentSecond = ((current.getHour() - int(current.getHour())) * 100); - if(currentSecond - mStartingSecond >= mDuration) - return true; + return new AiEscort(*this); } - ESM::Position pos = actor.getRefData().getPosition(); - bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY; - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - const ESM::Pathgrid *pathgrid = - MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); + bool AiEscort::execute (const MWWorld::Ptr& actor) + { + // If AiEscort has ran for as long or longer then the duration specified + // and the duration is not infinite, the package is complete. + if(mDuration != 0) + { + MWWorld::TimeStamp current = MWBase::Environment::get().getWorld()->getTimeStamp(); + unsigned int currentSecond = ((current.getHour() - int(current.getHour())) * 100); + if(currentSecond - mStartingSecond >= mDuration) + return true; + } + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + ESM::Position pos = actor.getRefData().getPosition(); + bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY; + const ESM::Pathgrid *pathgrid = + MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); - if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) - { - int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); - // Check if actor is near the border of an inactive cell. If so, disable AiEscort. - // FIXME: This *should* pause the AiEscort package instead of terminating it. - if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / 2. - 200)) + if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; + int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); + // Check if actor is near the border of an inactive cell. If so, disable AiEscort. + // FIXME: This *should* pause the AiEscort package instead of terminating it. + if(sideX * (pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / + 2.0 - 200)) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } } - } - if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) - { - int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); - // Check if actor is near the border of an inactive cell. If so, disable AiEscort. - // FIXME: This *should* pause the AiEscort package instead of terminating it. - if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / 2. - 200)) + if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; + int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); + // Check if actor is near the border of an inactive cell. If so, disable AiEscort. + // FIXME: This *should* pause the AiEscort package instead of terminating it. + if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / + 2.0 - 200)) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } } - } - if(!mPathFinder.isPathConstructed() || cellChange) - { - cellX = actor.getCell()->mCell->mData.mX; - cellY = actor.getCell()->mCell->mData.mY; - float xCell = 0; - float yCell = 0; - if (actor.getCell()->mCell->isExterior()) + if(!mPathFinder.isPathConstructed() || cellChange) { - xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; - yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; + cellX = actor.getCell()->mCell->mData.mX; + cellY = actor.getCell()->mCell->mData.mY; + float xCell = 0; + float yCell = 0; + if (actor.getCell()->mCell->isExterior()) + { + xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; + yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; + } + + ESM::Pathgrid::Point dest; + dest.mX = mX; + dest.mY = mY; + dest.mZ = mZ; + + ESM::Pathgrid::Point start; + start.mX = pos.pos[0]; + start.mY = pos.pos[1]; + start.mZ = pos.pos[2]; + + mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, true); } - ESM::Pathgrid::Point dest; - dest.mX = mX; - dest.mY = mY; - dest.mZ = mZ; - - ESM::Pathgrid::Point start; - start.mX = pos.pos[0]; - start.mY = pos.pos[1]; - start.mZ = pos.pos[2]; - - mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, 1); - } + if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } - if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) - { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; - } + const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mActorId, false); + const float* const leaderPos = actor.getRefData().getPosition().pos; + const float* const followerPos = follower.getRefData().getPosition().pos; + double differenceBetween[3]; - const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mActorId, false); - const float* const leaderPos = actor.getRefData().getPosition().pos; - const float* const followerPos = follower.getRefData().getPosition().pos; - double differenceBetween[3]; + for (short counter = 0; counter < 3; counter++) + differenceBetween[counter] = (leaderPos[counter] - followerPos[counter]); - for (short i = 0; i < 3; ++i) - differenceBetween[i] = (leaderPos[i] - followerPos[i]); + float distanceBetweenResult = + (differenceBetween[0] * differenceBetween[0]) + (differenceBetween[1] * differenceBetween[1]) + (differenceBetween[2] * + differenceBetween[2]); - float distanceBetweenResult = - (differenceBetween[0] * differenceBetween[0]) + (differenceBetween[1] * differenceBetween[1]) + (differenceBetween[2] * differenceBetween[2]); + if(distanceBetweenResult <= mMaxDist * mMaxDist) + { + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); + MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + mMaxDist = 470; + } + else + { + // Stop moving if the player is to far away + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + mMaxDist = 330; + } - if(distanceBetweenResult <= mMaxDist * mMaxDist) - { - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]); - MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; - mMaxDist = 470; + return false; } - else + + int AiEscort::getTypeId() const { - // Stop moving if the player is to far away - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - mMaxDist = 330; + return 2; } - - return false; -} - -int MWMechanics::AiEscort::getTypeId() const -{ - return 2; } diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index 4307ed284..90365c16b 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -2,99 +2,106 @@ #include "movement.hpp" -#include "../mwworld/class.hpp" #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/player.hpp" namespace { float sgn(float a) { - if(a > 0) return 1.; - else return -1.; + if(a > 0) + return 1.0; + return -1.0; } } -MWMechanics::AiTravel::AiTravel(float x, float y, float z) -: mX(x),mY(y),mZ(z),mPathFinder() -{ -} - -MWMechanics::AiTravel *MWMechanics::AiTravel::clone() const +namespace MWMechanics { - return new AiTravel(*this); -} + AiTravel::AiTravel(float x, float y, float z) + : mX(x),mY(y),mZ(z),mPathFinder() + { + } -bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor) -{ - const ESM::Pathgrid *pathgrid = - MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); + AiTravel *MWMechanics::AiTravel::clone() const + { + return new AiTravel(*this); + } - ESM::Position pos = actor.getRefData().getPosition(); + bool AiTravel::execute (const MWWorld::Ptr& actor) + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + ESM::Position pos = actor.getRefData().getPosition(); bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY; + const ESM::Pathgrid *pathgrid = + MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) - { - int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); - //check if actor is near the border of an inactive cell. If so, disable aitravel. - if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX*(ESM::Land::REAL_SIZE/2. - 200)) + if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; + int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); + //check if actor is near the border of an inactive cell. If so, disable aitravel. + if(sideX * (pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / + 2.0 - 200)) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } } - } - if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) - { - int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); - //check if actor is near the border of an inactive cell. If so, disable aitravel. - if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY*(ESM::Land::REAL_SIZE/2. - 200)) + if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; + int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); + //check if actor is near the border of an inactive cell. If so, disable aitravel. + if(sideY * (pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / + 2.0 - 200)) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } } - } - if(!mPathFinder.isPathConstructed() ||cellChange) - { - cellX = actor.getCell()->mCell->mData.mX; - cellY = actor.getCell()->mCell->mData.mY; - float xCell = 0; - float yCell = 0; - if (actor.getCell()->mCell->isExterior()) + if(!mPathFinder.isPathConstructed() || cellChange) { - xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; - yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; + cellX = actor.getCell()->mCell->mData.mX; + cellY = actor.getCell()->mCell->mData.mY; + float xCell = 0; + float yCell = 0; + + if (actor.getCell()->mCell->isExterior()) + { + xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; + yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; + } + + ESM::Pathgrid::Point dest; + dest.mX = mX; + dest.mY = mY; + dest.mZ = mZ; + + ESM::Pathgrid::Point start; + start.mX = pos.pos[0]; + start.mY = pos.pos[1]; + start.mZ = pos.pos[2]; + + mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, true); } - ESM::Pathgrid::Point dest; - dest.mX = mX; - dest.mY = mY; - dest.mZ = mZ; + if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } - ESM::Pathgrid::Point start; - start.mX = pos.pos[0]; - start.mY = pos.pos[1]; - start.mZ = pos.pos[2]; + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); + MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle, false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; - mPathFinder.buildPath(start, dest, pathgrid, xCell, yCell, 1); + return false; } - if(mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2])) + int AiTravel::getTypeId() const { - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; - return true; + return 1; } - - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]); - MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; - - return false; } -int MWMechanics::AiTravel::getTypeId() const -{ - return 1; -} diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 1530804cd..8f7926236 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -14,316 +14,324 @@ namespace { float sgn(float a) { - if(a > 0) return 1.0; - else return -1.0; + if(a > 0) + return 1.0; + return -1.0; } } -MWMechanics::AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat): - mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat) +namespace MWMechanics { - for(unsigned short counter = 0; counter < mIdle.size(); counter++) + AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat): + mDistance(distance), mDuration(duration), mTimeOfDay(timeOfDay), mIdle(idle), mRepeat(repeat) { - if(mIdle[counter] >= 127 || mIdle[counter] < 0) - mIdle[counter] = 0; - } + for(unsigned short counter = 0; counter < mIdle.size(); counter++) + { + if(mIdle[counter] >= 127 || mIdle[counter] < 0) + mIdle[counter] = 0; + } - if(mDistance < 0) - mDistance = 0; - if(mDuration < 0) - mDuration = 0; - if(mDuration == 0) - mTimeOfDay = 0; - - srand(time(NULL)); - mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp(); - mPlayedIdle = 0; - mPathgrid = NULL; - mIdleChanceMultiplier = - MWBase::Environment::get().getWorld()->getStore().get().find("fIdleChanceMultiplier")->getFloat(); - - mStoredAvailableNodes = false; - mChooseAction = true; - mIdleNow = false; - mMoveNow = false; - mWalking = false; -} + if(mDistance < 0) + mDistance = 0; + if(mDuration < 0) + mDuration = 0; + if(mDuration == 0) + mTimeOfDay = 0; -MWMechanics::AiPackage * MWMechanics::AiWander::clone() const -{ - return new AiWander(*this); -} + srand(time(NULL)); + mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mPlayedIdle = 0; + mPathgrid = NULL; + mIdleChanceMultiplier = + MWBase::Environment::get().getWorld()->getStore().get().find("fIdleChanceMultiplier")->getFloat(); + + mStoredAvailableNodes = false; + mChooseAction = true; + mIdleNow = false; + mMoveNow = false; + mWalking = false; + } -bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) -{ - if(mDuration) + AiPackage * MWMechanics::AiWander::clone() const { - // End package if duration is complete or mid-night hits: - MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); - if(currentTime.getHour() >= mStartTime.getHour() + mDuration) + return new AiWander(*this); + } + + bool AiWander::execute (const MWWorld::Ptr& actor) + { + if(mDuration) { - if(!mRepeat) + // End package if duration is complete or mid-night hits: + MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + if(currentTime.getHour() >= mStartTime.getHour() + mDuration) { - stopWalking(actor); - return true; + if(!mRepeat) + { + stopWalking(actor); + return true; + } + else + mStartTime = currentTime; } - else - mStartTime = currentTime; - } - else if(int(currentTime.getHour()) == 0 && currentTime.getDay() != mStartTime.getDay()) - { - if(!mRepeat) + else if(int(currentTime.getHour()) == 0 && currentTime.getDay() != mStartTime.getDay()) { - stopWalking(actor); - return true; + if(!mRepeat) + { + stopWalking(actor); + return true; + } + else + mStartTime = currentTime; } - else - mStartTime = currentTime; } - } - ESM::Position pos = actor.getRefData().getPosition(); + ESM::Position pos = actor.getRefData().getPosition(); - if(!mStoredAvailableNodes) - { - mStoredAvailableNodes = true; - mPathgrid = - MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); + if(!mStoredAvailableNodes) + { + mStoredAvailableNodes = true; + mPathgrid = + MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); - mCellX = actor.getCell()->mCell->mData.mX; - mCellY = actor.getCell()->mCell->mData.mY; + mCellX = actor.getCell()->mCell->mData.mX; + mCellY = actor.getCell()->mCell->mData.mY; - if(!mPathgrid) - mDistance = 0; - else if(mPathgrid->mPoints.empty()) - mDistance = 0; + if(!mPathgrid) + mDistance = 0; + else if(mPathgrid->mPoints.empty()) + mDistance = 0; - if(mDistance) - { - mXCell = 0; - mYCell = 0; - if(actor.getCell()->mCell->isExterior()) + if(mDistance) { - mXCell = mCellX * ESM::Land::REAL_SIZE; - mYCell = mCellY * ESM::Land::REAL_SIZE; - } + mXCell = 0; + mYCell = 0; + if(actor.getCell()->mCell->isExterior()) + { + mXCell = mCellX * ESM::Land::REAL_SIZE; + mYCell = mCellY * ESM::Land::REAL_SIZE; + } - Ogre::Vector3 npcPos(actor.getRefData().getPosition().pos); - npcPos[0] = npcPos[0] - mXCell; - npcPos[1] = npcPos[1] - mYCell; + Ogre::Vector3 npcPos(actor.getRefData().getPosition().pos); + npcPos[0] = npcPos[0] - mXCell; + npcPos[1] = npcPos[1] - mYCell; - for(unsigned int counter = 0; counter < mPathgrid->mPoints.size(); counter++) - { - Ogre::Vector3 nodePos(mPathgrid->mPoints[counter].mX, mPathgrid->mPoints[counter].mY, mPathgrid->mPoints[counter].mZ); - if(npcPos.squaredDistance(nodePos) <= mDistance * mDistance) - mAllowedNodes.push_back(mPathgrid->mPoints[counter]); - } - if(!mAllowedNodes.empty()) - { - Ogre::Vector3 firstNodePos(mAllowedNodes[0].mX, mAllowedNodes[0].mY, mAllowedNodes[0].mZ); - float closestNode = npcPos.squaredDistance(firstNodePos); - unsigned int index = 0; - for(unsigned int counterThree = 1; counterThree < mAllowedNodes.size(); counterThree++) + for(unsigned int counter = 0; counter < mPathgrid->mPoints.size(); counter++) { - Ogre::Vector3 nodePos(mAllowedNodes[counterThree].mX, mAllowedNodes[counterThree].mY, mAllowedNodes[counterThree].mZ); - float tempDist = npcPos.squaredDistance(nodePos); - if(tempDist < closestNode) - index = counterThree; + Ogre::Vector3 nodePos(mPathgrid->mPoints[counter].mX, mPathgrid->mPoints[counter].mY, + mPathgrid->mPoints[counter].mZ); + if(npcPos.squaredDistance(nodePos) <= mDistance * mDistance) + mAllowedNodes.push_back(mPathgrid->mPoints[counter]); + } + if(!mAllowedNodes.empty()) + { + Ogre::Vector3 firstNodePos(mAllowedNodes[0].mX, mAllowedNodes[0].mY, mAllowedNodes[0].mZ); + float closestNode = npcPos.squaredDistance(firstNodePos); + unsigned int index = 0; + for(unsigned int counterThree = 1; counterThree < mAllowedNodes.size(); counterThree++) + { + Ogre::Vector3 nodePos(mAllowedNodes[counterThree].mX, mAllowedNodes[counterThree].mY, + mAllowedNodes[counterThree].mZ); + float tempDist = npcPos.squaredDistance(nodePos); + if(tempDist < closestNode) + index = counterThree; + } + mCurrentNode = mAllowedNodes[index]; + mAllowedNodes.erase(mAllowedNodes.begin() + index); } - mCurrentNode = mAllowedNodes[index]; - mAllowedNodes.erase(mAllowedNodes.begin() + index); - } - if(mAllowedNodes.empty()) - mDistance = 0; + if(mAllowedNodes.empty()) + mDistance = 0; + } } - } - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - bool cellChange = actor.getCell()->mCell->mData.mX != mCellX || actor.getCell()->mCell->mData.mY != mCellY; + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + bool cellChange = actor.getCell()->mCell->mData.mX != mCellX || actor.getCell()->mCell->mData.mY != mCellY; - if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) - { - int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); - // Check if actor is near the border of an inactive cell. If so, disable AiWander. - // FIXME: This *should* pause the AiWander package instead of terminating it. - if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / 2.0 - 200)) + if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) { - stopWalking(actor); - return true; + int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); + // Check if actor is near the border of an inactive cell. If so, disable AiWander. + // FIXME: This *should* pause the AiWander package instead of terminating it. + if(sideX * (pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / + 2.0 - 200)) + { + stopWalking(actor); + return true; + } } - } - if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) - { - int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); - // Check if actor is near the border of an inactive cell. If so, disable AiWander. - // FIXME: This *should* pause the AiWander package instead of terminating it. - if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / 2.0 - 200)) + if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) { - stopWalking(actor); - return true; + int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); + // Check if actor is near the border of an inactive cell. If so, disable AiWander. + // FIXME: This *should* pause the AiWander package instead of terminating it. + if(sideY * (pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / + 2.0 - 200)) + { + stopWalking(actor); + return true; + } } - } - // Don't try to move if you are in a new cell (ie: positioncell command called) but still play idles. - if(mDistance && (cellChange || (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY))) - mDistance = 0; - - if(mChooseAction) - { - mPlayedIdle = 0; - unsigned short idleRoll = 0; + // Don't try to move if you are in a new cell (ie: positioncell command called) but still play idles. + if(mDistance && (cellChange || (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY))) + mDistance = 0; - for(unsigned int counter = 1; counter < mIdle.size(); counter++) + if(mChooseAction) { - unsigned short idleChance = mIdleChanceMultiplier * mIdle[counter]; - unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mIdleChanceMultiplier)); - if(randSelect < idleChance && randSelect > idleRoll) + mPlayedIdle = 0; + unsigned short idleRoll = 0; + + for(unsigned int counter = 1; counter < mIdle.size(); counter++) { - mPlayedIdle = counter; - idleRoll = randSelect; + unsigned short idleChance = mIdleChanceMultiplier * mIdle[counter]; + unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mIdleChanceMultiplier)); + if(randSelect < idleChance && randSelect > idleRoll) + { + mPlayedIdle = counter; + idleRoll = randSelect; + } } - } - if(!mPlayedIdle && mDistance) - { - mChooseAction = false; - mMoveNow = true; - } - else - { - // Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander: - MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); - mStartTime = currentTime; - playIdle(actor, mPlayedIdle + 1); - mChooseAction = false; - mIdleNow = true; + if(!mPlayedIdle && mDistance) + { + mChooseAction = false; + mMoveNow = true; + } + else + { + // Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander: + MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mStartTime = currentTime; + playIdle(actor, mPlayedIdle + 1); + mChooseAction = false; + mIdleNow = true; + } } - } - if(mIdleNow) - { - if(!checkIdle(actor, mPlayedIdle + 1)) + if(mIdleNow) { - mPlayedIdle = 0; - mIdleNow = false; - mChooseAction = true; + if(!checkIdle(actor, mPlayedIdle + 1)) + { + mPlayedIdle = 0; + mIdleNow = false; + mChooseAction = true; + } } - } - if(mMoveNow && mDistance) - { - if(!mPathFinder.isPathConstructed()) + if(mMoveNow && mDistance) { - unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size()); - Ogre::Vector3 destNodePos(mAllowedNodes[randNode].mX, mAllowedNodes[randNode].mY, mAllowedNodes[randNode].mZ); + if(!mPathFinder.isPathConstructed()) + { + unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size()); + Ogre::Vector3 destNodePos(mAllowedNodes[randNode].mX, mAllowedNodes[randNode].mY, mAllowedNodes[randNode].mZ); - ESM::Pathgrid::Point dest; - dest.mX = destNodePos[0] + mXCell; - dest.mY = destNodePos[1] + mYCell; - dest.mZ = destNodePos[2]; + ESM::Pathgrid::Point dest; + dest.mX = destNodePos[0] + mXCell; + dest.mY = destNodePos[1] + mYCell; + dest.mZ = destNodePos[2]; - ESM::Pathgrid::Point start; - start.mX = pos.pos[0]; - start.mY = pos.pos[1]; - start.mZ = pos.pos[2]; + ESM::Pathgrid::Point start; + start.mX = pos.pos[0]; + start.mY = pos.pos[1]; + start.mZ = pos.pos[2]; - mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, 0); + mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, false); - if(mPathFinder.isPathConstructed()) - { - // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): - ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; - mAllowedNodes.erase(mAllowedNodes.begin() + randNode); - mAllowedNodes.push_back(mCurrentNode); - mCurrentNode = temp; + if(mPathFinder.isPathConstructed()) + { + // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): + ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; + mAllowedNodes.erase(mAllowedNodes.begin() + randNode); + mAllowedNodes.push_back(mCurrentNode); + mCurrentNode = temp; + + mMoveNow = false; + mWalking = true; + } + // Choose a different node and delete this one from possible nodes because it is uncreachable: + else + mAllowedNodes.erase(mAllowedNodes.begin() + randNode); + } + } + if(mWalking) + { + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); + MWBase::Environment::get().getWorld()->rotateObject(actor, 0, 0, zAngle,false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + + // Unclog path nodes by allowing the NPC to be a small distance away from the center. This way two NPCs can be + // at the same path node at the same time and both will complete instead of endlessly walking into eachother: + Ogre::Vector3 destNodePos(mCurrentNode.mX, mCurrentNode.mY, mCurrentNode.mZ); + Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos); + actorPos[0] = actorPos[0] - mXCell; + actorPos[1] = actorPos[1] - mYCell; + float distance = actorPos.squaredDistance(destNodePos); + + if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) + { + stopWalking(actor); mMoveNow = false; - mWalking = true; + mWalking = false; + mChooseAction = true; } - // Choose a different node and delete this one from possible nodes because it is uncreachable: - else - mAllowedNodes.erase(mAllowedNodes.begin() + randNode); } + + return false; } - if(mWalking) + int AiWander::getTypeId() const { - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1]); - MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; - - // Unclog path nodes by allowing the NPC to be a small distance away from the center. This way two NPCs can be - // at the same path node at the same time and both will complete instead of endlessly walking into eachother: - Ogre::Vector3 destNodePos(mCurrentNode.mX, mCurrentNode.mY, mCurrentNode.mZ); - Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos); - actorPos[0] = actorPos[0] - mXCell; - actorPos[1] = actorPos[1] - mYCell; - float distance = actorPos.squaredDistance(destNodePos); - - if(distance < 1200 || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) - { - stopWalking(actor); - mMoveNow = false; - mWalking = false; - mChooseAction = true; - } + return 0; } - return false; -} - -int MWMechanics::AiWander::getTypeId() const -{ - return 0; -} - -void MWMechanics::AiWander::stopWalking(const MWWorld::Ptr& actor) -{ - mPathFinder.clearPath(); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; -} + void AiWander::stopWalking(const MWWorld::Ptr& actor) + { + mPathFinder.clearPath(); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + } -void MWMechanics::AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) -{ - if(idleSelect == 2) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle2", 0, 1); - else if(idleSelect == 3) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); - else if(idleSelect == 4) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle4", 0, 1); - else if(idleSelect == 5) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle5", 0, 1); - else if(idleSelect == 6) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle6", 0, 1); - else if(idleSelect == 7) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle7", 0, 1); - else if(idleSelect == 8) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle8", 0, 1); - else if(idleSelect == 9) - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle9", 0, 1); -} + void AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) + { + if(idleSelect == 2) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle2", 0, 1); + else if(idleSelect == 3) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); + else if(idleSelect == 4) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle4", 0, 1); + else if(idleSelect == 5) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle5", 0, 1); + else if(idleSelect == 6) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle6", 0, 1); + else if(idleSelect == 7) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle7", 0, 1); + else if(idleSelect == 8) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle8", 0, 1); + else if(idleSelect == 9) + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle9", 0, 1); + } -bool MWMechanics::AiWander::checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) -{ - if(idleSelect == 2) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle2"); - else if(idleSelect == 3) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle3"); - else if(idleSelect == 4) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle4"); - else if(idleSelect == 5) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle5"); - else if(idleSelect == 6) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle6"); - else if(idleSelect == 7) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle7"); - else if(idleSelect == 8) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle8"); - else if(idleSelect == 9) - return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle9"); - else - return false; + bool AiWander::checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) + { + if(idleSelect == 2) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle2"); + else if(idleSelect == 3) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle3"); + else if(idleSelect == 4) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle4"); + else if(idleSelect == 5) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle5"); + else if(idleSelect == 6) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle6"); + else if(idleSelect == 7) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle7"); + else if(idleSelect == 8) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle8"); + else if(idleSelect == 9) + return MWBase::Environment::get().getMechanicsManager()->checkAnimationPlaying(actor, "idle9"); + else + return false; + } } diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index d3a44e0f9..986595a9a 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -205,7 +205,7 @@ namespace MWMechanics return true; ESM::Pathgrid::Point nextPoint = *mPath.begin(); - if(distanceZCorrected(nextPoint, x, y, z) < 20) + if(distanceZCorrected(nextPoint, x, y, z) < 40) { mPath.pop_front(); if(mPath.empty()) From 512dcdc73575f9fdd2be21ef0ecef5f1c246059c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 2 Jun 2013 09:50:29 +0200 Subject: [PATCH 094/213] updated changelog --- readme.txt | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/readme.txt b/readme.txt index 230150d6e..2cf5c5551 100644 --- a/readme.txt +++ b/readme.txt @@ -94,6 +94,53 @@ Allowed options: CHANGELOG +0.24.0 + +Bug #284: Book's text misalignment +Bug #445: Camera able to get slightly below floor / terrain +Bug #582: Seam issue in Red Mountain +Bug #632: Journal Next Button shows white square +Bug #653: IndexedStore ignores index +Bug #694: Parser does not recognize float values starting with . +Bug #699: Resource handling broken with Ogre 1.9 trunk +Bug #718: components/esm/loadcell is using the mwworld subsystem +Bug #729: Levelled item list tries to add nonexistent item +Bug #730: Arrow buttons in the settings menu do not work. +Bug #732: Erroneous behavior when binding keys +Bug #733: Unclickable dialogue topic +Bug #734: Book empty line problem +Bug #738: OnDeath only works with implicit references +Bug #740: Script compiler fails on scripts with special names +Bug #742: Wait while no clipping +Bug #743: Problem with changeweather console command +Bug #744: No wait dialogue after starting a new game +Bug #748: Player is not able to unselect objects with the console +Bug #751: AddItem should only spawn a message box when called from dialogue +Bug #752: The enter button has several functions in trade and looting that is not impelemted. +Bug #753: Fargoth's Ring Quest Strange Behavior +Bug #759: Second quest in mages guild does not work +Bug #763: Enchantment cast cost is wrong +Bug #770: The "Take" and "Close" buttons in the scroll GUI are stretched incorrectly +Bug #773: AIWander Isn't Being Passed The Correct idle Values +Bug #778: The journal can be opened at the start of a new game +Bug #779: Divayth Fyr starts as dead +Bug #787: "Batch count" on detailed FPS counter gets cut-off +Bug #788: chargen scroll layout does not match vanilla +Feature #60: Atlethics Skill +Feature #65: Security Skill +Feature #74: Interaction with non-load-doors +Feature #98: Render Weapon and Shield +Feature #102: AI Package: Escort, EscortCell +Feature #182: Advanced Journal GUI +Feature #288: Trading enhancements +Feature #405: Integrate "new game" into the menu +Feature #537: Highlight dialogue topic links +Feature #658: Rotate, RotateWorld script instructions and local rotations +Feature #690: Animation Layering +Feature #722: Night Eye/Blind magic effects +Feature #735: Move, MoveWorld script instructions. +Feature #760: Non-removable corpses + 0.23.0 Bug #522: Player collides with placeable items From b3595a6a2e42d715f3345bced12d346e7f1b4d07 Mon Sep 17 00:00:00 2001 From: pvdk Date: Sun, 2 Jun 2013 21:43:22 +0200 Subject: [PATCH 095/213] Fix for duplicate key/value pairs being written to settings.cfg, Bug #755 --- apps/launcher/maindialog.cpp | 4 ++++ apps/launcher/settings/gamesettings.cpp | 4 ++-- apps/launcher/settings/settingsbase.hpp | 20 ++++++++++++++++---- files/ui/playpage.ui | 19 +++++++++---------- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index e5da3431a..8cc476f53 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -310,6 +310,8 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) bool MainDialog::setupLauncherSettings() { + mLauncherSettings.setMultiValueEnabled(true); + QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); QStringList paths; @@ -427,6 +429,8 @@ bool MainDialog::setupGameSettings() bool MainDialog::setupGraphicsSettings() { + mGraphicsSettings.setMultiValueEnabled(false); + QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string()); diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 9a9b8df41..1b0a2e9bf 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -103,8 +103,8 @@ bool GameSettings::readFile(QTextStream &stream) if (keyRe.indexIn(line) != -1) { - QString key = keyRe.cap(1); - QString value = keyRe.cap(2); + QString key = keyRe.cap(1).trimmed(); + QString value = keyRe.cap(2).trimmed(); // Don't remove existing data entries if (key != QLatin1String("data")) diff --git a/apps/launcher/settings/settingsbase.hpp b/apps/launcher/settings/settingsbase.hpp index 21029b3ad..6bf2eff66 100644 --- a/apps/launcher/settings/settingsbase.hpp +++ b/apps/launcher/settings/settingsbase.hpp @@ -14,7 +14,7 @@ class SettingsBase { public: - SettingsBase() {} + SettingsBase() { mMultiValue = false; } ~SettingsBase() {} inline QString value(const QString &key, const QString &defaultValue = QString()) @@ -36,6 +36,11 @@ public: mSettings.insertMulti(key, value); } + inline void setMultiValueEnabled(bool enable) + { + mMultiValue = enable; + } + inline void remove(const QString &key) { mSettings.remove(key); @@ -66,8 +71,8 @@ public: if (keyRe.indexIn(line) != -1) { - QString key = keyRe.cap(1); - QString value = keyRe.cap(2); + QString key = keyRe.cap(1).trimmed(); + QString value = keyRe.cap(2).trimmed(); if (!sectionPrefix.isEmpty()) key.prepend(sectionPrefix); @@ -75,8 +80,13 @@ public: mSettings.remove(key); QStringList values = mCache.values(key); + if (!values.contains(value)) { - mCache.insertMulti(key, value); + if (mMultiValue) { + mCache.insertMulti(key, value); + } else { + mCache.insert(key, value); + } } } } @@ -94,6 +104,8 @@ public: private: Map mSettings; Map mCache; + + bool mMultiValue; }; #endif // SETTINGSBASE_HPP diff --git a/files/ui/playpage.ui b/files/ui/playpage.ui index c0320de1e..bf883b96e 100644 --- a/files/ui/playpage.ui +++ b/files/ui/playpage.ui @@ -2,9 +2,17 @@ PlayPage + + + 0 + 0 + 274 + 317 + + - + #Scroll { background-image: url(":/images/playpage-background.png"); @@ -13,15 +21,6 @@ } - - QFrame::StyledPanel - - - QFrame::Plain - - - 0 - 30 From 68bef59d89610fdcbb535df7f22296a7808901b2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 3 Jun 2013 10:15:19 +0200 Subject: [PATCH 096/213] updated changelog again --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 2cf5c5551..67c02cc61 100644 --- a/readme.txt +++ b/readme.txt @@ -118,6 +118,7 @@ Bug #748: Player is not able to unselect objects with the console Bug #751: AddItem should only spawn a message box when called from dialogue Bug #752: The enter button has several functions in trade and looting that is not impelemted. Bug #753: Fargoth's Ring Quest Strange Behavior +Bug #755: Launcher writes duplicate lines into settings.cfg Bug #759: Second quest in mages guild does not work Bug #763: Enchantment cast cost is wrong Bug #770: The "Take" and "Close" buttons in the scroll GUI are stretched incorrectly From daab4f55a3648a2adfb4f71780909e4b88752efc Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 6 Jun 2013 22:13:30 +0200 Subject: [PATCH 097/213] Use Morrowind's fonts --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/engine.cpp | 2 +- apps/openmw/mwgui/bookpage.cpp | 15 +- apps/openmw/mwgui/dialogue.cpp | 10 +- apps/openmw/mwgui/fontloader.cpp | 238 +++++++++++++++++++++++ apps/openmw/mwgui/fontloader.hpp | 25 +++ apps/openmw/mwgui/formatting.cpp | 4 +- apps/openmw/mwgui/journalbooks.cpp | 24 +-- apps/openmw/mwgui/windowmanagerimp.cpp | 7 +- apps/openmw/mwgui/windowmanagerimp.hpp | 2 +- components/to_utf8/gen_iconv.cpp | 4 +- components/to_utf8/tables_gen.hpp | 259 +++++++++++++++++++++++++ components/to_utf8/to_utf8.cpp | 6 + components/to_utf8/to_utf8.hpp | 3 +- files/mygui/core.skin | 1 - files/mygui/openmw_font.xml | 45 +---- files/mygui/openmw_settings.xml | 2 +- 17 files changed, 579 insertions(+), 70 deletions(-) create mode 100644 apps/openmw/mwgui/fontloader.cpp create mode 100644 apps/openmw/mwgui/fontloader.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 660e45115..31f6fca79 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -33,7 +33,7 @@ add_openmw_dir (mwgui enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview - tradeitemmodel companionitemmodel pickpocketitemmodel + tradeitemmodel companionitemmodel pickpocketitemmodel fontloader ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index abc951726..89d34bd41 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -380,7 +380,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mEnvironment.setWindowManager (new MWGui::WindowManager( mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), - mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage)); + mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding)); if (mNewGame) mEnvironment.getWindowManager()->setNewGame(true); diff --git a/apps/openmw/mwgui/bookpage.cpp b/apps/openmw/mwgui/bookpage.cpp index ef688be1b..94f834a4d 100644 --- a/apps/openmw/mwgui/bookpage.cpp +++ b/apps/openmw/mwgui/bookpage.cpp @@ -223,6 +223,9 @@ struct TypesetBookImpl::Typesetter : BookTypesetter Style * createStyle (char const * fontName, Colour fontColour) { + if (strcmp(fontName, "") == 0) + return createStyle(MyGUI::FontManager::getInstance().getDefaultFont().c_str(), fontColour); + for (Styles::iterator i = mBook->mStyles.begin (); i != mBook->mStyles.end (); ++i) if (i->match (fontName, fontColour, fontColour, fontColour, 0)) return &*i; @@ -405,7 +408,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter while (!stream.eof () && !ucsLineBreak (stream.peek ()) && ucsBreakingSpace (stream.peek ())) { MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ()); - space_width += gi->advance; + if (gi) + space_width += gi->advance + gi->bearingX; stream.consume (); } @@ -414,7 +418,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter while (!stream.eof () && !ucsLineBreak (stream.peek ()) && !ucsBreakingSpace (stream.peek ())) { MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ()); - word_width += gi->advance + gi->bearingX; + if (gi) + word_width += gi->advance + gi->bearingX; word_height = line_height; ++character_count; stream.consume (); @@ -628,6 +633,9 @@ namespace { MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch); + if (!gi) + return; + MyGUI::FloatRect vr; vr.left = mCursor.left + gi->bearingX; @@ -647,7 +655,8 @@ namespace { MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch); - mCursor.left += gi->bearingX + gi->advance; + if (gi) + mCursor.left += gi->bearingX + gi->advance; } private: diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 2eacd973e..64c61abc0 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -115,7 +115,7 @@ namespace MWGui void Response::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map& topicLinks) const { - BookTypesetter::Style* title = typesetter->createStyle("EB Garamond", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f)); + BookTypesetter::Style* title = typesetter->createStyle("", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f)); typesetter->sectionBreak(9); if (mTitle != "") typesetter->write(title, to_utf8_span(mTitle.c_str())); @@ -159,7 +159,7 @@ namespace MWGui if (hyperLinks.size() && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation()) { - BookTypesetter::Style* style = typesetter->createStyle("EB Garamond", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f)); + BookTypesetter::Style* style = typesetter->createStyle("", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f)); size_t formatted = 0; // points to the first character that is not laid out yet for (std::map::iterator it = hyperLinks.begin(); it != hyperLinks.end(); ++it) { @@ -197,7 +197,7 @@ namespace MWGui void Response::addTopicLink(BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const { - BookTypesetter::Style* style = typesetter->createStyle("EB Garamond", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f)); + BookTypesetter::Style* style = typesetter->createStyle("", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f)); const MyGUI::Colour linkHot (143/255.f, 155/255.f, 218/255.f); const MyGUI::Colour linkNormal (112/255.f, 126/255.f, 207/255.f); @@ -215,7 +215,7 @@ namespace MWGui void Message::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map& topicLinks) const { - BookTypesetter::Style* title = typesetter->createStyle("EB Garamond", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f)); + BookTypesetter::Style* title = typesetter->createStyle("", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f)); typesetter->sectionBreak(9); typesetter->write(title, to_utf8_span(mText.c_str())); } @@ -465,7 +465,7 @@ namespace MWGui (*it)->write(typesetter, &mKeywordSearch, mTopicLinks); - BookTypesetter::Style* body = typesetter->createStyle("EB Garamond", MyGUI::Colour::White); + BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::White); // choices const MyGUI::Colour linkHot (223/255.f, 201/255.f, 159/255.f); diff --git a/apps/openmw/mwgui/fontloader.cpp b/apps/openmw/mwgui/fontloader.cpp new file mode 100644 index 000000000..ff160105a --- /dev/null +++ b/apps/openmw/mwgui/fontloader.cpp @@ -0,0 +1,238 @@ +#include "fontloader.hpp" + +#include +#include + +#include +#include +#include +#include +#include + +#include + +namespace +{ + unsigned long utf8ToUnicode(const std::string& utf8) + { + size_t i = 0; + unsigned long unicode; + size_t todo; + unsigned char ch = utf8[i++]; + if (ch <= 0x7F) + { + unicode = ch; + todo = 0; + } + else if (ch <= 0xBF) + { + throw std::logic_error("not a UTF-8 string"); + } + else if (ch <= 0xDF) + { + unicode = ch&0x1F; + todo = 1; + } + else if (ch <= 0xEF) + { + unicode = ch&0x0F; + todo = 2; + } + else if (ch <= 0xF7) + { + unicode = ch&0x07; + todo = 3; + } + else + { + throw std::logic_error("not a UTF-8 string"); + } + for (size_t j = 0; j < todo; ++j) + { + unsigned char ch = utf8[i++]; + if (ch < 0x80 || ch > 0xBF) + throw std::logic_error("not a UTF-8 string"); + unicode <<= 6; + unicode += ch & 0x3F; + } + if (unicode >= 0xD800 && unicode <= 0xDFFF) + throw std::logic_error("not a UTF-8 string"); + if (unicode > 0x10FFFF) + throw std::logic_error("not a UTF-8 string"); + + return unicode; + } +} + +namespace MWGui +{ + + FontLoader::FontLoader(ToUTF8::FromType encoding) + { + if (encoding == ToUTF8::WINDOWS_1252) + mEncoding = ToUTF8::CP437; + else + mEncoding = encoding; + } + + void FontLoader::loadAllFonts() + { + Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups (); + for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it) + { + Ogre::StringVectorPtr resourcesInThisGroup = Ogre::ResourceGroupManager::getSingleton ().findResourceNames (*it, "*.fnt"); + for (Ogre::StringVector::iterator resource = resourcesInThisGroup->begin(); resource != resourcesInThisGroup->end(); ++resource) + { + loadFont(*resource); + } + } + } + + + typedef struct + { + float x; + float y; + } Point; + + typedef struct + { + float u1; // appears unused, always 0 + Point top_left; + Point top_right; + Point bottom_left; + Point bottom_right; + float width; + float height; + float u2; // appears unused, always 0 + float kerning; + float ascent; + } GlyphInfo; + + void FontLoader::loadFont(const std::string &fileName) + { + Ogre::DataStreamPtr file = Ogre::ResourceGroupManager::getSingleton().openResource(fileName); + + float fontSize; + int one; + file->read(&fontSize, sizeof(fontSize)); + + file->read(&one, sizeof(int)); + assert(one == 1); + file->read(&one, sizeof(int)); + assert(one == 1); + + char name_[284]; + file->read(name_, sizeof(name_)); + std::string name(name_); + + GlyphInfo data[256]; + file->read(data, sizeof(data)); + file->close(); + + // Create the font texture + std::string bitmapFilename = "Fonts/" + std::string(name) + ".tex"; + Ogre::DataStreamPtr bitmapFile = Ogre::ResourceGroupManager::getSingleton().openResource(bitmapFilename); + + int width, height; + bitmapFile->read(&width, sizeof(int)); + bitmapFile->read(&height, sizeof(int)); + + std::vector textureData; + textureData.resize(width*height*4); + bitmapFile->read(&textureData[0], width*height*4); + bitmapFile->close(); + + std::string textureName = name; + Ogre::Image image; + image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA); + Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual(textureName, + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, + width, height, 0, Ogre::PF_BYTE_RGBA); + texture->loadImage(image); + + // Register the font with MyGUI + MyGUI::ResourceManualFont* font = static_cast( + MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont")); + // We need to emulate loading from XML because the data members are private as of mygui 3.2.0 + MyGUI::xml::Document xmlDocument; + MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont"); + + if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic")) + root->addAttribute("name", "Magic Cards"); + else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century")) + root->addAttribute("name", "Century Gothic"); + else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric")) + root->addAttribute("name", "Daedric"); + else + return; // no point in loading it, since there is no way of using additional fonts + + MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property"); + defaultHeight->addAttribute("key", "DefaultHeight"); + defaultHeight->addAttribute("value", fontSize); + MyGUI::xml::ElementPtr source = root->createChild("Property"); + source->addAttribute("key", "Source"); + source->addAttribute("value", std::string(textureName)); + MyGUI::xml::ElementPtr codes = root->createChild("Codes"); + + for(int i = 0; i < 256; i++) + { + int x1 = data[i].top_left.x*width; + int y1 = data[i].top_left.y*height; + int w = data[i].top_right.x*width - x1; + int h = data[i].bottom_left.y*height - y1; + + ToUTF8::Utf8Encoder encoder(mEncoding); + unsigned long unicodeVal = utf8ToUnicode(encoder.getUtf8(std::string(1, (unsigned char)(i)))); + + MyGUI::xml::ElementPtr code = codes->createChild("Code"); + code->addAttribute("index", unicodeVal); + code->addAttribute("coord", MyGUI::utility::toString(x1) + " " + + MyGUI::utility::toString(y1) + " " + + MyGUI::utility::toString(w) + " " + + MyGUI::utility::toString(h)); + code->addAttribute("advance", data[i].width); + code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " " + + MyGUI::utility::toString((fontSize-data[i].ascent))); + + // ASCII vertical bar, use this as text input cursor + if (i == 124) + { + MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code"); + cursorCode->addAttribute("index", MyGUI::FontCodeType::Cursor); + cursorCode->addAttribute("coord", MyGUI::utility::toString(x1) + " " + + MyGUI::utility::toString(y1) + " " + + MyGUI::utility::toString(w) + " " + + MyGUI::utility::toString(h)); + cursorCode->addAttribute("advance", data[i].width); + cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " " + + MyGUI::utility::toString((fontSize-data[i].ascent))); + } + } + + // These are required as well, but the fonts don't provide them + for (int i=0; i<3; ++i) + { + MyGUI::FontCodeType::Enum type; + if(i == 0) + type = MyGUI::FontCodeType::Selected; + else if (i == 1) + type = MyGUI::FontCodeType::SelectedBack; + else if (i == 2) + type = MyGUI::FontCodeType::NotDefined; + + MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code"); + cursorCode->addAttribute("index", type); + cursorCode->addAttribute("coord", "0 0 0 0"); + cursorCode->addAttribute("advance", "0"); + cursorCode->addAttribute("bearing", "0 0"); + + } + + font->deserialization(root, MyGUI::Version(3,2,0)); + + MyGUI::ResourceManager::getInstance().addResource(font); + } + +} diff --git a/apps/openmw/mwgui/fontloader.hpp b/apps/openmw/mwgui/fontloader.hpp new file mode 100644 index 000000000..7954b0875 --- /dev/null +++ b/apps/openmw/mwgui/fontloader.hpp @@ -0,0 +1,25 @@ +#ifndef MWGUI_FONTLOADER_H +#define MWGUI_FONTLOADER_H + +#include + +namespace MWGui +{ + + + /// @brief loads Morrowind's .fnt/.tex fonts for use with MyGUI and Ogre + class FontLoader + { + public: + FontLoader (ToUTF8::FromType encoding); + void loadAllFonts (); + + private: + ToUTF8::FromType mEncoding; + + void loadFont (const std::string& fileName); + }; + +} + +#endif diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index aebaf16a2..aeff573ae 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -202,14 +202,14 @@ namespace MWGui float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const { - std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont); + std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont); return MyGUI::FontManager::getInstance().getByName(fontName) ->getGlyphInfo(unicodeChar)->width; } float BookTextParser::currentFontHeight() const { - std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont); + std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont); return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight(); } diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 273985e3e..dbea10e77 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -189,14 +189,14 @@ book JournalBooks::createEmptyJournalBook () { BookTypesetter::Ptr typesetter = createTypesetter (); - BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f)); - BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black); + BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); + BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); typesetter->write (header, to_utf8_span ("You have no journal entries!")); typesetter->lineBreak (); typesetter->write (body, to_utf8_span ("You should have gone though the starting quest and got an initial quest.")); - BookTypesetter::Style* big = typesetter->createStyle ("EB Garamond 24", MyGUI::Colour::Black); + BookTypesetter::Style* big = typesetter->createStyle ("", MyGUI::Colour::Black); BookTypesetter::Style* test = typesetter->createStyle ("MonoFont", MyGUI::Colour::Blue); typesetter->sectionBreak (20); @@ -231,8 +231,8 @@ book JournalBooks::createJournalBook () { BookTypesetter::Ptr typesetter = createTypesetter (); - BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f)); - BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black); + BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); + BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); mModel->visitJournalEntries (0, AddJournalEntry (typesetter, body, header, true)); @@ -243,8 +243,8 @@ book JournalBooks::createTopicBook (uintptr_t topicId) { BookTypesetter::Ptr typesetter = createTypesetter (); - BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f)); - BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black); + BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); + BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); mModel->visitTopicName (topicId, AddTopicName (typesetter, header)); @@ -259,8 +259,8 @@ book JournalBooks::createQuestBook (uintptr_t questId) { BookTypesetter::Ptr typesetter = createTypesetter (); - BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f)); - BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black); + BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); + BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); mModel->visitQuestName (questId, AddQuestName (typesetter, header)); @@ -275,7 +275,7 @@ book JournalBooks::createTopicIndexBook () typesetter->setSectionAlignment (BookTypesetter::AlignCenter); - BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black); + BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); for (int i = 0; i < 26; ++i) { @@ -300,7 +300,7 @@ book JournalBooks::createTopicIndexBook () book JournalBooks::createTopicIndexBook (char character) { BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF); - BookTypesetter::Style* style = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black); + BookTypesetter::Style* style = typesetter->createStyle ("", MyGUI::Colour::Black); mModel->visitTopicNamesStartingWith (character, AddTopicLink (typesetter, style)); @@ -310,7 +310,7 @@ book JournalBooks::createTopicIndexBook (char character) book JournalBooks::createQuestIndexBook (bool activeOnly) { BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF); - BookTypesetter::Style* base = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black); + BookTypesetter::Style* base = typesetter->createStyle ("", MyGUI::Colour::Black); mModel->visitQuestNames (activeOnly, AddQuestLink (typesetter, base)); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 48c5aba6b..09ceb843d 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -42,6 +42,7 @@ #include "inventorywindow.hpp" #include "bookpage.hpp" #include "itemview.hpp" +#include "fontloader.hpp" namespace MWGui { @@ -49,7 +50,7 @@ namespace MWGui WindowManager::WindowManager( const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, - Translation::Storage& translationDataStorage) + Translation::Storage& translationDataStorage, ToUTF8::FromType encoding) : mGuiManager(NULL) , mRendering(ogre) , mHud(NULL) @@ -109,6 +110,10 @@ namespace MWGui mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath); mGui = mGuiManager->getGui(); + // Load fonts + FontLoader fontLoader (encoding); + fontLoader.loadAllFonts(); + //Register own widgets with MyGUI MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 71bd2c9a7..71686d59b 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -83,7 +83,7 @@ namespace MWGui WindowManager(const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, - Translation::Storage& translationDataStorage); + Translation::Storage& translationDataStorage, ToUTF8::FromType encoding); virtual ~WindowManager(); /** diff --git a/components/to_utf8/gen_iconv.cpp b/components/to_utf8/gen_iconv.cpp index dea68c1fa..8198b305d 100644 --- a/components/to_utf8/gen_iconv.cpp +++ b/components/to_utf8/gen_iconv.cpp @@ -46,7 +46,7 @@ void writeMissing(bool last) int write_table(const std::string &charset, const std::string &tableName) { // Write table header - cout << "static char " << tableName << "[] =\n{\n"; + cout << "static signed char " << tableName << "[] =\n{\n"; // Open conversion system iconv_t cd = iconv_open ("UTF-8", charset.c_str()); @@ -106,6 +106,8 @@ int main() "\n"; write_table("WINDOWS-1252", "windows_1252"); + write_table("CP437", "cp437"); + // Close namespace cout << "\n}\n\n"; diff --git a/components/to_utf8/tables_gen.hpp b/components/to_utf8/tables_gen.hpp index a1d4b6d80..14e66eac1 100644 --- a/components/to_utf8/tables_gen.hpp +++ b/components/to_utf8/tables_gen.hpp @@ -790,6 +790,265 @@ static signed char windows_1252[] = 2, -61, -66, 0, 0, 0, 2, -61, -65, 0, 0, 0 }; +static signed char cp437[] = +{ + 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 2, 0, 0, 0, 0, + 1, 3, 0, 0, 0, 0, + 1, 4, 0, 0, 0, 0, + 1, 5, 0, 0, 0, 0, + 1, 6, 0, 0, 0, 0, + 1, 7, 0, 0, 0, 0, + 1, 8, 0, 0, 0, 0, + 1, 9, 0, 0, 0, 0, + 1, 10, 0, 0, 0, 0, + 1, 11, 0, 0, 0, 0, + 1, 12, 0, 0, 0, 0, + 1, 13, 0, 0, 0, 0, + 1, 14, 0, 0, 0, 0, + 1, 15, 0, 0, 0, 0, + 1, 16, 0, 0, 0, 0, + 1, 17, 0, 0, 0, 0, + 1, 18, 0, 0, 0, 0, + 1, 19, 0, 0, 0, 0, + 1, 20, 0, 0, 0, 0, + 1, 21, 0, 0, 0, 0, + 1, 22, 0, 0, 0, 0, + 1, 23, 0, 0, 0, 0, + 1, 24, 0, 0, 0, 0, + 1, 25, 0, 0, 0, 0, + 1, 26, 0, 0, 0, 0, + 1, 27, 0, 0, 0, 0, + 1, 28, 0, 0, 0, 0, + 1, 29, 0, 0, 0, 0, + 1, 30, 0, 0, 0, 0, + 1, 31, 0, 0, 0, 0, + 1, 32, 0, 0, 0, 0, + 1, 33, 0, 0, 0, 0, + 1, 34, 0, 0, 0, 0, + 1, 35, 0, 0, 0, 0, + 1, 36, 0, 0, 0, 0, + 1, 37, 0, 0, 0, 0, + 1, 38, 0, 0, 0, 0, + 1, 39, 0, 0, 0, 0, + 1, 40, 0, 0, 0, 0, + 1, 41, 0, 0, 0, 0, + 1, 42, 0, 0, 0, 0, + 1, 43, 0, 0, 0, 0, + 1, 44, 0, 0, 0, 0, + 1, 45, 0, 0, 0, 0, + 1, 46, 0, 0, 0, 0, + 1, 47, 0, 0, 0, 0, + 1, 48, 0, 0, 0, 0, + 1, 49, 0, 0, 0, 0, + 1, 50, 0, 0, 0, 0, + 1, 51, 0, 0, 0, 0, + 1, 52, 0, 0, 0, 0, + 1, 53, 0, 0, 0, 0, + 1, 54, 0, 0, 0, 0, + 1, 55, 0, 0, 0, 0, + 1, 56, 0, 0, 0, 0, + 1, 57, 0, 0, 0, 0, + 1, 58, 0, 0, 0, 0, + 1, 59, 0, 0, 0, 0, + 1, 60, 0, 0, 0, 0, + 1, 61, 0, 0, 0, 0, + 1, 62, 0, 0, 0, 0, + 1, 63, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 1, 65, 0, 0, 0, 0, + 1, 66, 0, 0, 0, 0, + 1, 67, 0, 0, 0, 0, + 1, 68, 0, 0, 0, 0, + 1, 69, 0, 0, 0, 0, + 1, 70, 0, 0, 0, 0, + 1, 71, 0, 0, 0, 0, + 1, 72, 0, 0, 0, 0, + 1, 73, 0, 0, 0, 0, + 1, 74, 0, 0, 0, 0, + 1, 75, 0, 0, 0, 0, + 1, 76, 0, 0, 0, 0, + 1, 77, 0, 0, 0, 0, + 1, 78, 0, 0, 0, 0, + 1, 79, 0, 0, 0, 0, + 1, 80, 0, 0, 0, 0, + 1, 81, 0, 0, 0, 0, + 1, 82, 0, 0, 0, 0, + 1, 83, 0, 0, 0, 0, + 1, 84, 0, 0, 0, 0, + 1, 85, 0, 0, 0, 0, + 1, 86, 0, 0, 0, 0, + 1, 87, 0, 0, 0, 0, + 1, 88, 0, 0, 0, 0, + 1, 89, 0, 0, 0, 0, + 1, 90, 0, 0, 0, 0, + 1, 91, 0, 0, 0, 0, + 1, 92, 0, 0, 0, 0, + 1, 93, 0, 0, 0, 0, + 1, 94, 0, 0, 0, 0, + 1, 95, 0, 0, 0, 0, + 1, 96, 0, 0, 0, 0, + 1, 97, 0, 0, 0, 0, + 1, 98, 0, 0, 0, 0, + 1, 99, 0, 0, 0, 0, + 1, 100, 0, 0, 0, 0, + 1, 101, 0, 0, 0, 0, + 1, 102, 0, 0, 0, 0, + 1, 103, 0, 0, 0, 0, + 1, 104, 0, 0, 0, 0, + 1, 105, 0, 0, 0, 0, + 1, 106, 0, 0, 0, 0, + 1, 107, 0, 0, 0, 0, + 1, 108, 0, 0, 0, 0, + 1, 109, 0, 0, 0, 0, + 1, 110, 0, 0, 0, 0, + 1, 111, 0, 0, 0, 0, + 1, 112, 0, 0, 0, 0, + 1, 113, 0, 0, 0, 0, + 1, 114, 0, 0, 0, 0, + 1, 115, 0, 0, 0, 0, + 1, 116, 0, 0, 0, 0, + 1, 117, 0, 0, 0, 0, + 1, 118, 0, 0, 0, 0, + 1, 119, 0, 0, 0, 0, + 1, 120, 0, 0, 0, 0, + 1, 121, 0, 0, 0, 0, + 1, 122, 0, 0, 0, 0, + 1, 123, 0, 0, 0, 0, + 1, 124, 0, 0, 0, 0, + 1, 125, 0, 0, 0, 0, + 1, 126, 0, 0, 0, 0, + 1, 127, 0, 0, 0, 0, + 2, -61, -121, 0, 0, 0, + 2, -61, -68, 0, 0, 0, + 2, -61, -87, 0, 0, 0, + 2, -61, -94, 0, 0, 0, + 2, -61, -92, 0, 0, 0, + 2, -61, -96, 0, 0, 0, + 2, -61, -91, 0, 0, 0, + 2, -61, -89, 0, 0, 0, + 2, -61, -86, 0, 0, 0, + 2, -61, -85, 0, 0, 0, + 2, -61, -88, 0, 0, 0, + 2, -61, -81, 0, 0, 0, + 2, -61, -82, 0, 0, 0, + 2, -61, -84, 0, 0, 0, + 2, -61, -124, 0, 0, 0, + 2, -61, -123, 0, 0, 0, + 2, -61, -119, 0, 0, 0, + 2, -61, -90, 0, 0, 0, + 2, -61, -122, 0, 0, 0, + 2, -61, -76, 0, 0, 0, + 2, -61, -74, 0, 0, 0, + 2, -61, -78, 0, 0, 0, + 2, -61, -69, 0, 0, 0, + 2, -61, -71, 0, 0, 0, + 2, -61, -65, 0, 0, 0, + 2, -61, -106, 0, 0, 0, + 2, -61, -100, 0, 0, 0, + 2, -62, -94, 0, 0, 0, + 2, -62, -93, 0, 0, 0, + 2, -62, -91, 0, 0, 0, + 3, -30, -126, -89, 0, 0, + 2, -58, -110, 0, 0, 0, + 2, -61, -95, 0, 0, 0, + 2, -61, -83, 0, 0, 0, + 2, -61, -77, 0, 0, 0, + 2, -61, -70, 0, 0, 0, + 2, -61, -79, 0, 0, 0, + 2, -61, -111, 0, 0, 0, + 2, -62, -86, 0, 0, 0, + 2, -62, -70, 0, 0, 0, + 2, -62, -65, 0, 0, 0, + 3, -30, -116, -112, 0, 0, + 2, -62, -84, 0, 0, 0, + 2, -62, -67, 0, 0, 0, + 2, -62, -68, 0, 0, 0, + 2, -62, -95, 0, 0, 0, + 2, -62, -85, 0, 0, 0, + 2, -62, -69, 0, 0, 0, + 3, -30, -106, -111, 0, 0, + 3, -30, -106, -110, 0, 0, + 3, -30, -106, -109, 0, 0, + 3, -30, -108, -126, 0, 0, + 3, -30, -108, -92, 0, 0, + 3, -30, -107, -95, 0, 0, + 3, -30, -107, -94, 0, 0, + 3, -30, -107, -106, 0, 0, + 3, -30, -107, -107, 0, 0, + 3, -30, -107, -93, 0, 0, + 3, -30, -107, -111, 0, 0, + 3, -30, -107, -105, 0, 0, + 3, -30, -107, -99, 0, 0, + 3, -30, -107, -100, 0, 0, + 3, -30, -107, -101, 0, 0, + 3, -30, -108, -112, 0, 0, + 3, -30, -108, -108, 0, 0, + 3, -30, -108, -76, 0, 0, + 3, -30, -108, -84, 0, 0, + 3, -30, -108, -100, 0, 0, + 3, -30, -108, -128, 0, 0, + 3, -30, -108, -68, 0, 0, + 3, -30, -107, -98, 0, 0, + 3, -30, -107, -97, 0, 0, + 3, -30, -107, -102, 0, 0, + 3, -30, -107, -108, 0, 0, + 3, -30, -107, -87, 0, 0, + 3, -30, -107, -90, 0, 0, + 3, -30, -107, -96, 0, 0, + 3, -30, -107, -112, 0, 0, + 3, -30, -107, -84, 0, 0, + 3, -30, -107, -89, 0, 0, + 3, -30, -107, -88, 0, 0, + 3, -30, -107, -92, 0, 0, + 3, -30, -107, -91, 0, 0, + 3, -30, -107, -103, 0, 0, + 3, -30, -107, -104, 0, 0, + 3, -30, -107, -110, 0, 0, + 3, -30, -107, -109, 0, 0, + 3, -30, -107, -85, 0, 0, + 3, -30, -107, -86, 0, 0, + 3, -30, -108, -104, 0, 0, + 3, -30, -108, -116, 0, 0, + 3, -30, -106, -120, 0, 0, + 3, -30, -106, -124, 0, 0, + 3, -30, -106, -116, 0, 0, + 3, -30, -106, -112, 0, 0, + 3, -30, -106, -128, 0, 0, + 2, -50, -79, 0, 0, 0, + 2, -61, -97, 0, 0, 0, + 2, -50, -109, 0, 0, 0, + 2, -49, -128, 0, 0, 0, + 2, -50, -93, 0, 0, 0, + 2, -49, -125, 0, 0, 0, + 2, -62, -75, 0, 0, 0, + 2, -49, -124, 0, 0, 0, + 2, -50, -90, 0, 0, 0, + 2, -50, -104, 0, 0, 0, + 2, -50, -87, 0, 0, 0, + 2, -50, -76, 0, 0, 0, + 3, -30, -120, -98, 0, 0, + 2, -49, -122, 0, 0, 0, + 2, -50, -75, 0, 0, 0, + 3, -30, -120, -87, 0, 0, + 3, -30, -119, -95, 0, 0, + 2, -62, -79, 0, 0, 0, + 3, -30, -119, -91, 0, 0, + 3, -30, -119, -92, 0, 0, + 3, -30, -116, -96, 0, 0, + 3, -30, -116, -95, 0, 0, + 2, -61, -73, 0, 0, 0, + 3, -30, -119, -120, 0, 0, + 2, -62, -80, 0, 0, 0, + 3, -30, -120, -103, 0, 0, + 2, -62, -73, 0, 0, 0, + 3, -30, -120, -102, 0, 0, + 3, -30, -127, -65, 0, 0, + 2, -62, -78, 0, 0, 0, + 3, -30, -106, -96, 0, 0, + 2, -62, -96, 0, 0, 0 +}; } diff --git a/components/to_utf8/to_utf8.cpp b/components/to_utf8/to_utf8.cpp index 1de15d79c..59a9aff80 100644 --- a/components/to_utf8/to_utf8.cpp +++ b/components/to_utf8/to_utf8.cpp @@ -63,6 +63,12 @@ Utf8Encoder::Utf8Encoder(const FromType sourceEncoding): translationArray = ToUTF8::windows_1251; break; } + case ToUTF8::CP437: + { + translationArray = ToUTF8::cp437; + break; + } + default: { assert(0); diff --git a/components/to_utf8/to_utf8.hpp b/components/to_utf8/to_utf8.hpp index 839aa36aa..3f20a51f8 100644 --- a/components/to_utf8/to_utf8.hpp +++ b/components/to_utf8/to_utf8.hpp @@ -12,8 +12,9 @@ namespace ToUTF8 { WINDOWS_1250, // Central ane Eastern European languages WINDOWS_1251, // Cyrillic languages - WINDOWS_1252 // Used by English version of Morrowind (and + WINDOWS_1252, // Used by English version of Morrowind (and // probably others) + CP437 // Used for fonts (*.fnt) if data files encoding is 1252. Otherwise, uses the same encoding as the data files. }; FromType calculateEncoding(const std::string& encodingName); diff --git a/files/mygui/core.skin b/files/mygui/core.skin index e52080fe0..ea3e2debc 100644 --- a/files/mygui/core.skin +++ b/files/mygui/core.skin @@ -2,7 +2,6 @@ - diff --git a/files/mygui/openmw_font.xml b/files/mygui/openmw_font.xml index ef4300326..726bfb281 100644 --- a/files/mygui/openmw_font.xml +++ b/files/mygui/openmw_font.xml @@ -23,56 +23,21 @@ - - - - + + + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/files/mygui/openmw_settings.xml b/files/mygui/openmw_settings.xml index c63f962fb..37d235968 100644 --- a/files/mygui/openmw_settings.xml +++ b/files/mygui/openmw_settings.xml @@ -1,7 +1,7 @@ - + From 10165d3c6b7f68113c38904892eb9145506f9594 Mon Sep 17 00:00:00 2001 From: Glorf Date: Sun, 9 Jun 2013 00:34:27 +0200 Subject: [PATCH 098/213] Feature #468 --- apps/opencs/CMakeLists.txt | 1 + apps/opencs/model/settings/usersettings.cpp | 56 +++++++++ apps/opencs/model/settings/usersettings.hpp | 1 + apps/opencs/view/doc/view.cpp | 8 +- .../view/settings/usersettingsdialog.cpp | 22 +++- .../view/settings/usersettingsdialog.hpp | 3 + apps/opencs/view/settings/windowpage.cpp | 114 ++++++++++++++++++ apps/opencs/view/settings/windowpage.hpp | 28 +++++ 8 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 apps/opencs/view/settings/windowpage.cpp create mode 100644 apps/opencs/view/settings/windowpage.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 9787719af..158f7d7f1 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -79,6 +79,7 @@ opencs_units (view/settings abstractwidget usersettingsdialog editorpage + windowpage ) opencs_units_noqt (view/settings diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index aabda86b3..c7305a888 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -135,3 +136,58 @@ void CSMSettings::UserSettings::getSettings(QTextStream &stream, SectionMap &sec } sections.insert(section, settings); } + +QString CSMSettings::UserSettings::getSettingValue(QString section, QString setting) +{ + Files::ConfigurationManager configMgr; + QString userPath = QString::fromStdString(configMgr.getUserPath().string()); + QStringList list; + + list.append(QString("opencs.cfg")); + list.append(userPath + QString("opencs.cfg")); + + + CSMSettings::SectionMap sectionMap; + + foreach (const QString &path, list) + { + qDebug() << "Loading config file:" << qPrintable(path); + QFile file(path); + + if (file.exists()) + { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error opening OpenCS configuration file")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(QObject::tr("
Could not open %0 for reading

\ + Please make sure you have the right permissions \ + and try again.
").arg(file.fileName())); + msgBox.exec(); + return QString(); + } + + QTextStream stream(&file); + stream.setCodec(QTextCodec::codecForName("UTF-8")); + + getSettings(stream, sectionMap); + } + + file.close(); + } + + if(sectionMap.find(section) == sectionMap.end()) + return QString(); + + CSMSettings::SettingMap *settings = sectionMap.value(section); + + if(settings->find(setting) == settings->end()) + return QString(); + + CSMSettings::SettingContainer *settingContainer = settings->value(setting); + + return settingContainer->getValue(); +} + diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 343702eda..4c82054db 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -34,6 +34,7 @@ namespace CSMSettings { QFile *openFile (const QString &); bool writeFile(QFile *file, QMap §ions); void getSettings (QTextStream &stream, SectionMap &settings); + QString getSettingValue(QString section, QString setting); private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 2857f4a54..1e19e6db4 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "../../model/doc/document.hpp" #include "../world/subviews.hpp" @@ -179,7 +180,12 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews) { - resize (300, 300); /// \todo get default size from settings and set reasonable minimal size + QString width = CSMSettings::UserSettings::instance().getSettingValue(QString("Window Size"), QString("Width")); + QString height = CSMSettings::UserSettings::instance().getSettingValue(QString("Window Size"), QString("Height")); + if(width==QString() || height==QString()) + resize(800, 600); + else + resize (width.toInt(), height.toInt()); mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks); diff --git a/apps/opencs/view/settings/usersettingsdialog.cpp b/apps/opencs/view/settings/usersettingsdialog.cpp index 012fc0408..4474f6e46 100644 --- a/apps/opencs/view/settings/usersettingsdialog.cpp +++ b/apps/opencs/view/settings/usersettingsdialog.cpp @@ -9,13 +9,14 @@ #include #include #include +#include #include "blankpage.hpp" #include "editorpage.hpp" +#include "windowpage.hpp" #include "../../model/settings/support.hpp" #include "settingwidget.hpp" -#include CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) : QMainWindow (parent), mStackedWidget (0) @@ -76,9 +77,10 @@ void CSVSettings::UserSettingsDialog::buildPages() setDockOptions (QMainWindow::AllowNestedDocks); //uncomment to test with sample editor page. //createSamplePage(); - createPage("Page1"); + /*createPage("Page1"); createPage("Page2"); - createPage("Page3"); + createPage("Page3");*/ + createWindowPage(); } void CSVSettings::UserSettingsDialog::createSamplePage() @@ -95,6 +97,20 @@ void CSVSettings::UserSettingsDialog::createSamplePage() &(CSMSettings::UserSettings::instance()), SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &))); } +void CSVSettings::UserSettingsDialog::createWindowPage() +{ + //add pages to stackedwidget and items to listwidget + CSVSettings::AbstractPage *page + = new CSVSettings::WindowPage(this); + + mStackedWidget->addWidget (page); + + new QListWidgetItem (page->objectName(), mListWidget); + + connect ( page, SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)), + &(CSMSettings::UserSettings::instance()), SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &))); +} + void CSVSettings::UserSettingsDialog::positionWindow () { QRect scr = QApplication::desktop()->screenGeometry(); diff --git a/apps/opencs/view/settings/usersettingsdialog.hpp b/apps/opencs/view/settings/usersettingsdialog.hpp index 31d40ca01..8407493ee 100644 --- a/apps/opencs/view/settings/usersettingsdialog.hpp +++ b/apps/opencs/view/settings/usersettingsdialog.hpp @@ -45,6 +45,9 @@ namespace CSVSettings { void writeSettings(); void createSamplePage(); + //Pages + void createWindowPage(); + template void createPage (const QString &title) { diff --git a/apps/opencs/view/settings/windowpage.cpp b/apps/opencs/view/settings/windowpage.cpp new file mode 100644 index 000000000..e8677fa42 --- /dev/null +++ b/apps/opencs/view/settings/windowpage.cpp @@ -0,0 +1,114 @@ +#include "windowpage.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_MAC +#include +#endif + +#include "../../model/settings/usersettings.hpp" +#include "groupblock.hpp" +#include "toggleblock.hpp" + +CSVSettings::WindowPage::WindowPage(QWidget *parent): + AbstractPage("Window Size", parent) +{ + // Hacks to get the stylesheet look properly +#ifdef Q_OS_MAC + QPlastiqueStyle *style = new QPlastiqueStyle; + //profilesComboBox->setStyle(style); +#endif + + setupUi(); +} + +void CSVSettings::WindowPage::setupUi() +{ + GroupBlockDef customWindowSize (QString ("Custom Window Size")); + GroupBlockDef definedWindowSize (QString ("Pre-Defined Window Size")); + GroupBlockDef windowSizeToggle (QString ("Window Size")); + CustomBlockDef windowSize (QString ("Window Size")); + + + /////////////////////////////// + //custom window size properties + /////////////////////////////// + + //custom width + SettingsItemDef *widthItem = new SettingsItemDef ("Width", "640"); + widthItem->widget = WidgetDef (Widget_LineEdit); + widthItem->widget.widgetWidth = 45; + + //custom height + SettingsItemDef *heightItem = new SettingsItemDef ("Height", "480"); + heightItem->widget = WidgetDef (Widget_LineEdit); + heightItem->widget.widgetWidth = 45; + heightItem->widget.caption = "x"; + + customWindowSize.properties << widthItem << heightItem; + customWindowSize.widgetOrientation = Orient_Horizontal; + customWindowSize.isVisible = false; + + + //pre-defined + SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480"); + WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox); + widthByHeightWidget.widgetWidth = 90; + *(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768" << "1440x900"; + + QStringList *widthProxy = new QStringList; + QStringList *heightProxy = new QStringList; + + (*widthProxy) << "Width" << "640" << "800" << "1024" << "1440"; + (*heightProxy) << "Height" << "480" << "600" << "768" << "900"; + + *(widthByHeightItem->proxyList) << widthProxy << heightProxy; + + widthByHeightItem->widget = widthByHeightWidget; + + definedWindowSize.properties << widthByHeightItem; + definedWindowSize.isProxy = true; + definedWindowSize.isVisible = false; + + // window size toggle + windowSizeToggle.captions << "Pre-Defined" << "Custom"; + windowSizeToggle.widgetOrientation = Orient_Vertical; + windowSizeToggle.isVisible = false; + + //define a widget for each group in the toggle + for (int i = 0; i < 2; i++) + windowSizeToggle.widgets << new WidgetDef (Widget_RadioButton); + + windowSizeToggle.widgets.at(0)->isDefault = false; + + windowSize.blockDefList << &windowSizeToggle << &definedWindowSize << &customWindowSize; + windowSize.defaultValue = "Custom"; + + QGridLayout *pageLayout = new QGridLayout(this); + + setLayout (pageLayout); + + mAbstractBlocks << buildBlock (windowSize); + + foreach (AbstractBlock *block, mAbstractBlocks) + { + connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)), + this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) ); + } +} + +void CSVSettings::WindowPage::initializeWidgets (const CSMSettings::SettingMap &settings) +{ + //iterate each item in each blocks in this section + //validate the corresponding setting against the defined valuelist if any. + for (AbstractBlockList::Iterator it_block = mAbstractBlocks.begin(); + it_block != mAbstractBlocks.end(); ++it_block) + (*it_block)->updateSettings (settings); +} diff --git a/apps/opencs/view/settings/windowpage.hpp b/apps/opencs/view/settings/windowpage.hpp new file mode 100644 index 000000000..7978263fc --- /dev/null +++ b/apps/opencs/view/settings/windowpage.hpp @@ -0,0 +1,28 @@ +#ifndef WINDOWPAGE_H +#define WINDOWPAGE_H + +#include "abstractpage.hpp" + +class QGroupBox; + +namespace CSVSettings { + + class UserSettings; + class AbstractBlock; + + class WindowPage : public AbstractPage + { + Q_OBJECT + + public: + + WindowPage(QWidget *parent = 0); + + void setupUi(); + void initializeWidgets (const CSMSettings::SettingMap &settings); + + signals: + void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue); + }; +} +#endif //WINDOWPAGE_H From d13430e2b874512b87cd556ef9915e1d9b4c57ec Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 9 Jun 2013 20:59:31 +0400 Subject: [PATCH 099/213] Fix for CMake > 2.8.9 on OS X --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ee938206..04ff2fe17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,10 @@ if (APPLE) set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app") set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}") + + set(CMAKE_EXE_LINKER_FLAGS "-F /Library/Frameworks") + set(CMAKE_SHARED_LINKER_FLAGS "-F /Library/Frameworks") + set(CMAKE_MODULE_LINKER_FLAGS "-F /Library/Frameworks") endif (APPLE) # Macros From a3b2a76e608f8765658475a4283b63c73aac2e94 Mon Sep 17 00:00:00 2001 From: fstp Date: Sun, 9 Jun 2013 23:08:57 +0200 Subject: [PATCH 100/213] Added virtual destructors to classes LocalMapBase and EffectEditorBase. --- apps/openmw/mwgui/mapwindow.cpp | 4 ++++ apps/openmw/mwgui/mapwindow.hpp | 1 + apps/openmw/mwgui/spellcreationdialog.cpp | 4 ++++ apps/openmw/mwgui/spellcreationdialog.hpp | 2 +- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 4a78238ce..7098853af 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -34,6 +34,10 @@ namespace MWGui { } + LocalMapBase::~LocalMapBase() + { + } + void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop) { mLocalMap = widget; diff --git a/apps/openmw/mwgui/mapwindow.hpp b/apps/openmw/mwgui/mapwindow.hpp index 18c81a060..3aefc398c 100644 --- a/apps/openmw/mwgui/mapwindow.hpp +++ b/apps/openmw/mwgui/mapwindow.hpp @@ -14,6 +14,7 @@ namespace MWGui { public: LocalMapBase(); + virtual ~LocalMapBase(); void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop=false); void setCellPrefix(const std::string& prefix); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 45cf1b0aa..c4c1be711 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -416,6 +416,10 @@ namespace MWGui mAddEffectDialog.setVisible (false); } + EffectEditorBase::~EffectEditorBase() + { + } + void EffectEditorBase::startEditing () { // get the list of magic effects that are known to the player diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index 5ad306fbe..61b888491 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -84,7 +84,7 @@ namespace MWGui { public: EffectEditorBase(); - + virtual ~EffectEditorBase(); protected: std::map mButtonMapping; // maps button ID to effect ID From 4eede86ce64dbee18c54928ed9a5ad22bbc34b3e Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Sun, 9 Jun 2013 23:27:47 -0500 Subject: [PATCH 101/213] Moved journal open/close sound effect playback to JournalWindowImpl, and have opening sound play only if the player has the journal. --- apps/openmw/mwgui/journalwindow.cpp | 10 +++++++--- apps/openmw/mwinput/inputmanagerimp.cpp | 3 +-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 5b84c99a5..e7cb9916f 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -183,7 +183,12 @@ namespace if (!MWBase::Environment::get().getWindowManager ()->getJournalAllowed ()) { MWBase::Environment::get().getWindowManager()->popGuiMode (); - } + } + else + { + // play opening sound only if the player has the journal + MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0); + } mModel->load (); setBookMode (); @@ -213,6 +218,7 @@ namespace void close() { + MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); mModel->unload (); getPage (LeftBookPage)->showPage (Book (), 0); @@ -432,8 +438,6 @@ namespace void notifyClose(MyGUI::Widget* _sender) { - MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); - MWBase::Environment::get().getWindowManager ()->popGuiMode (); } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 00c520de9..e9a0e5089 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -658,12 +658,11 @@ namespace MWInput if(gameMode) { - MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0); mWindows.pushGuiMode(MWGui::GM_Journal); } else if(mWindows.getMode() == MWGui::GM_Journal) { - MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); + mWindows.popGuiMode(); } // .. but don't touch any other mode. From 9d6d200d228e2f03cecc1264f8333442eb6c2c93 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 10 Jun 2013 10:25:02 +0200 Subject: [PATCH 102/213] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 390a2d721..630f6ff39 100644 --- a/credits.txt +++ b/credits.txt @@ -32,6 +32,7 @@ Jacob Essex (Yacoby) Jannik Heller (scrawl) Jason Hooks (jhooks) Joel Graff (graffy) +John Blomberg (fstp) Jordan Milne Julien Voisin (jvoisin/ap0) Karl-Felix Glatzer (k1ll) From 98e5cb6d7b6b33144bec9649e2f92ec4e570474d Mon Sep 17 00:00:00 2001 From: fstp Date: Mon, 10 Jun 2013 15:10:39 +0200 Subject: [PATCH 103/213] Added ifdef to keep backward compatibility with the FFmpeg library. --- apps/openmw/mwrender/videoplayer.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 87ae8175d..1b5eddc21 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -32,9 +32,16 @@ namespace MWRender extern "C" { -#include -#include -#include + #include + #include + #include + + // From libavformat version 55.0.100 and onward the declaration of av_gettime() is removed from libavformat/avformat.h and moved + // to libavutil/time.h + // https://github.com/FFmpeg/FFmpeg/commit/06a83505992d5f49846c18507a6c3eb8a47c650e + #if AV_VERSION_INT(55, 0, 100) <= AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO) + #include + #endif } #define MAX_AUDIOQ_SIZE (5 * 16 * 1024) From b5caa25e5c5b80cd3526083aeec47902995c2617 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Mon, 10 Jun 2013 19:42:38 -0500 Subject: [PATCH 104/213] Just move check if player owns journal to inputmanagerimp.cpp - prevents playing sound when going to main menu. --- apps/openmw/mwgui/journalwindow.cpp | 10 +++------- apps/openmw/mwinput/inputmanagerimp.cpp | 5 +++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index e7cb9916f..89ee42934 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -184,11 +184,6 @@ namespace { MWBase::Environment::get().getWindowManager()->popGuiMode (); } - else - { - // play opening sound only if the player has the journal - MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0); - } mModel->load (); setBookMode (); @@ -218,7 +213,7 @@ namespace void close() { - MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); + mModel->unload (); getPage (LeftBookPage)->showPage (Book (), 0); @@ -438,6 +433,7 @@ namespace void notifyClose(MyGUI::Widget* _sender) { + MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); MWBase::Environment::get().getWindowManager ()->popGuiMode (); } @@ -476,4 +472,4 @@ namespace MWGui::JournalWindow * MWGui::JournalWindow::create (JournalViewModel::Ptr Model) { return new JournalWindowImpl (Model); -} +} \ No newline at end of file diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index e9a0e5089..9f149ac33 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -656,13 +656,14 @@ namespace MWInput // Toggle between game mode and journal mode bool gameMode = !mWindows.isGuiMode(); - if(gameMode) + if(gameMode && MWBase::Environment::get().getWindowManager ()->getJournalAllowed()) { + MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0); mWindows.pushGuiMode(MWGui::GM_Journal); } else if(mWindows.getMode() == MWGui::GM_Journal) { - + MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); mWindows.popGuiMode(); } // .. but don't touch any other mode. From fd25616cab06903425eabb09157dc865e015e594 Mon Sep 17 00:00:00 2001 From: darkf Date: Tue, 11 Jun 2013 20:10:43 -0700 Subject: [PATCH 105/213] launcher: Properly quit if settings write fails. --- apps/launcher/maindialog.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index e5da3431a..d0b3a2def 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -608,8 +608,10 @@ void MainDialog::closeEvent(QCloseEvent *event) void MainDialog::play() { - if (!writeSettings()) + if (!writeSettings()) { qApp->quit(); + return; + } // Launch the game detached startProgram(QString("openmw"), true); From fb462f1b1af68ca441f3179441b316d12ba299cb Mon Sep 17 00:00:00 2001 From: darkf Date: Tue, 11 Jun 2013 20:12:22 -0700 Subject: [PATCH 106/213] launcher: Throw error if no data files are selected --- apps/launcher/maindialog.cpp | 11 +++++++++++ apps/launcher/settings/gamesettings.hpp | 1 + 2 files changed, 12 insertions(+) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index d0b3a2def..a5fe8dcae 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -531,6 +531,17 @@ bool MainDialog::writeSettings() } } + if(!mGameSettings.hasMaster()) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
You do not have any master files selected.

\ + Please select one and try again.
")); + msgBox.exec(); + return false; + } + // Game settings QFile file(userPath + QString("openmw.cfg")); diff --git a/apps/launcher/settings/gamesettings.hpp b/apps/launcher/settings/gamesettings.hpp index 7a17ef9af..55b2107e2 100644 --- a/apps/launcher/settings/gamesettings.hpp +++ b/apps/launcher/settings/gamesettings.hpp @@ -43,6 +43,7 @@ public: inline QStringList getDataDirs() { return mDataDirs; } inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); } inline QString getDataLocal() {return mDataLocal; } + inline bool hasMaster() { return mSettings.count(QString("master")) > 0; } QStringList values(const QString &key, const QStringList &defaultValues = QStringList()); bool readFile(QTextStream &stream); From fc0f04324c4b7ee26355efbd8d9191bd920023b0 Mon Sep 17 00:00:00 2001 From: darkf Date: Tue, 11 Jun 2013 20:56:40 -0700 Subject: [PATCH 107/213] Remove some superfluous mSkyManager NULL checks --- apps/openmw/mwrender/renderingmanager.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a5dc8ec68..34a792435 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -401,29 +401,24 @@ void RenderingManager::setWaterHeight(const float height) void RenderingManager::skyEnable () { - if(mSkyManager) mSkyManager->enable(); - mOcclusionQuery->setSunNode(mSkyManager->getSunNode()); } void RenderingManager::skyDisable () { - if(mSkyManager) - mSkyManager->disable(); + mSkyManager->disable(); } void RenderingManager::skySetHour (double hour) { - if(mSkyManager) - mSkyManager->setHour(hour); + mSkyManager->setHour(hour); } void RenderingManager::skySetDate (int day, int month) { - if(mSkyManager) - mSkyManager->setDate(day, month); + mSkyManager->setDate(day, month); } int RenderingManager::skyGetMasserPhase() const @@ -438,8 +433,7 @@ int RenderingManager::skyGetSecundaPhase() const } void RenderingManager::skySetMoonColour (bool red){ - if(mSkyManager) - mSkyManager->setMoonColour(red); + mSkyManager->setMoonColour(red); } bool RenderingManager::toggleRenderMode(int mode) From 2fd4d71774e25703c6c4e3c4b7b952297ba3e390 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Tue, 11 Jun 2013 23:00:12 -0500 Subject: [PATCH 108/213] trim whitespace from key and value while reading settings file - stops ugly buildup in settings.cfg, and correctly reads settings from it. --- apps/launcher/settings/settingsbase.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/launcher/settings/settingsbase.hpp b/apps/launcher/settings/settingsbase.hpp index 21029b3ad..8320d56a1 100644 --- a/apps/launcher/settings/settingsbase.hpp +++ b/apps/launcher/settings/settingsbase.hpp @@ -66,8 +66,8 @@ public: if (keyRe.indexIn(line) != -1) { - QString key = keyRe.cap(1); - QString value = keyRe.cap(2); + QString key = keyRe.cap(1).trimmed(); + QString value = keyRe.cap(2).trimmed(); if (!sectionPrefix.isEmpty()) key.prepend(sectionPrefix); From 548f4d683f0105ce4d2dd85382350108f275706d Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 12 Jun 2013 12:36:35 +0200 Subject: [PATCH 109/213] Globalization of user settings --- apps/opencs/editor.cpp | 11 ++++ apps/opencs/editor.hpp | 2 + apps/opencs/model/settings/usersettings.cpp | 54 +++++++++++++------ apps/opencs/model/settings/usersettings.hpp | 28 +++++----- .../view/settings/usersettingsdialog.cpp | 46 ++-------------- .../view/settings/usersettingsdialog.hpp | 2 - 6 files changed, 70 insertions(+), 73 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 8dc5366a9..991d59537 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -61,6 +61,17 @@ void CS::Editor::setupDataFiles() QString path = QString::fromStdString(iter->string()); mFileDialog.addFiles(path); } + + //Settings setup + QStringList settingFiles; + QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); + + settingFiles.append(QString("opencs.cfg")); + settingFiles.append(userPath + QString("opencs.cfg")); + + mUserSettings.setSettingsFiles(settingFiles); + mUserSettings.readSettings(); + } void CS::Editor::createDocument() diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 1c4bcb1ee..380e434c2 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -10,6 +10,7 @@ #include "view/doc/viewmanager.hpp" #include "view/doc/startup.hpp" #include "view/doc/filedialog.hpp" +#include "model/settings/usersettings.hpp" namespace CS { @@ -17,6 +18,7 @@ namespace CS { Q_OBJECT + CSMSettings::UserSettings mUserSettings; CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; CSVDoc::StartupDialogue mStartup; diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index c7305a888..79de124c2 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -30,17 +30,25 @@ namespace boost } /* namespace boost */ #endif /* (BOOST_VERSION <= 104600) */ +CSMSettings::UserSettings *CSMSettings::UserSettings::mUserSettingsInstance = 0; CSMSettings::UserSettings::UserSettings() { + assert(!mUserSettingsInstance); mUserSettingsInstance = this; } CSMSettings::UserSettings::~UserSettings() { + mUserSettingsInstance = 0; } -QFile *CSMSettings::UserSettings::openFile (const QString &filename) +CSMSettings::SectionMap CSMSettings::UserSettings::getSettingsMap() const +{ + return mSectionMap; +} + +QFile *CSMSettings::UserSettings::openFile (const QString &filename) const { QFile *file = new QFile(filename); @@ -64,7 +72,7 @@ QFile *CSMSettings::UserSettings::openFile (const QString &filename) return file; } -bool CSMSettings::UserSettings::writeFile(QFile *file, QMap &settings) +bool CSMSettings::UserSettings::writeFile(QFile *file, QMap &settings) const { if (!file) return false; @@ -89,7 +97,7 @@ bool CSMSettings::UserSettings::writeFile(QFile *file, QMap").arg(file.fileName())); msgBox.exec(); - return QString(); + return; } QTextStream stream(&file); stream.setCodec(QTextCodec::codecForName("UTF-8")); + - getSettings(stream, sectionMap); + getSettings(stream, mSectionMap); } file.close(); } +} - if(sectionMap.find(section) == sectionMap.end()) +void CSMSettings::UserSettings::setSettingsFiles(QStringList files) +{ + mSettingsFiles = files; +} + +QStringList CSMSettings::UserSettings::getSettingsFiles () const +{ + return mSettingsFiles; +} + +QString CSMSettings::UserSettings::getSettingValue(QString section, QString setting) const +{ + if(mSectionMap.find(section) == mSectionMap.end()) return QString(); - CSMSettings::SettingMap *settings = sectionMap.value(section); + CSMSettings::SettingMap *settings = mSectionMap.value(section); if(settings->find(setting) == settings->end()) return QString(); @@ -191,3 +205,9 @@ QString CSMSettings::UserSettings::getSettingValue(QString section, QString sett return settingContainer->getValue(); } +const CSMSettings::UserSettings& CSMSettings::UserSettings::instance() +{ + assert(mUserSettingsInstance); + return *mUserSettingsInstance; +} + diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 4c82054db..6a2628fd1 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -24,23 +24,27 @@ namespace CSMSettings { public: - static UserSettings &instance() - { - static UserSettings instance; + UserSettings(); + ~UserSettings(); + + static const UserSettings& instance(); - return instance; - } + void readSettings(); + void setSettingsFiles(QStringList files); - QFile *openFile (const QString &); - bool writeFile(QFile *file, QMap §ions); - void getSettings (QTextStream &stream, SectionMap &settings); - QString getSettingValue(QString section, QString setting); + QFile *openFile (const QString &) const; + bool writeFile(QFile *file, QMap §ions) const; + void getSettings (QTextStream &stream, SectionMap &settings) const; + QStringList getSettingsFiles () const; + CSMSettings::SectionMap getSettingsMap() const; + QString getSettingValue(QString section, QString setting) const; private: - UserSettings *mUserSettingsInstance; - UserSettings(); - ~UserSettings(); + static UserSettings *mUserSettingsInstance; + + CSMSettings::SectionMap mSectionMap; + QStringList mSettingsFiles; UserSettings (UserSettings const &); //not implemented void operator= (UserSettings const &); //not implemented diff --git a/apps/opencs/view/settings/usersettingsdialog.cpp b/apps/opencs/view/settings/usersettingsdialog.cpp index 4474f6e46..d657ba06b 100644 --- a/apps/opencs/view/settings/usersettingsdialog.cpp +++ b/apps/opencs/view/settings/usersettingsdialog.cpp @@ -23,7 +23,7 @@ CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) : { setWindowTitle(QString::fromUtf8 ("User Settings")); buildPages(); - setWidgetStates (loadSettings()); + setWidgetStates (CSMSettings::UserSettings::instance().getSettingsMap()); positionWindow (); connect (mListWidget, @@ -119,46 +119,6 @@ void CSVSettings::UserSettingsDialog::positionWindow () } -CSMSettings::SectionMap CSVSettings::UserSettingsDialog::loadSettings () -{ - QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); - - mPaths.append(QString("opencs.cfg")); - mPaths.append(userPath + QString("opencs.cfg")); - - CSMSettings::SectionMap settingsMap; - - foreach (const QString &path, mPaths) - { - qDebug() << "Loading config file:" << qPrintable(path); - QFile file(path); - - if (file.exists()) - { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error opening OpenCS configuration file")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(QObject::tr("
Could not open %0 for reading

\ - Please make sure you have the right permissions \ - and try again.
").arg(file.fileName())); - msgBox.exec(); - return settingsMap; - } - - QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-8")); - - CSMSettings::UserSettings::instance().getSettings(stream, settingsMap); - } - - file.close(); - } - - return settingsMap; -} void CSVSettings::UserSettingsDialog::writeSettings() { @@ -170,7 +130,9 @@ void CSVSettings::UserSettingsDialog::writeSettings() settings [page->objectName()] = page->getSettings(); } - CSMSettings::UserSettings::instance().writeFile(CSMSettings::UserSettings::instance().openFile(mPaths.back()), settings); + QStringList paths = CSMSettings::UserSettings::instance().getSettingsFiles(); + + CSMSettings::UserSettings::instance().writeFile(CSMSettings::UserSettings::instance().openFile(paths.back()), settings); } diff --git a/apps/opencs/view/settings/usersettingsdialog.hpp b/apps/opencs/view/settings/usersettingsdialog.hpp index 8407493ee..71a4cb2f8 100644 --- a/apps/opencs/view/settings/usersettingsdialog.hpp +++ b/apps/opencs/view/settings/usersettingsdialog.hpp @@ -25,7 +25,6 @@ namespace CSVSettings { { Q_OBJECT - QStringList mPaths; QListWidget *mListWidget; QStackedWidget *mStackedWidget; Files::ConfigurationManager mCfgMgr; @@ -41,7 +40,6 @@ namespace CSVSettings { void setWidgetStates (CSMSettings::SectionMap settingsMap); void buildPages(); void positionWindow (); - CSMSettings::SectionMap loadSettings(); void writeSettings(); void createSamplePage(); From 918a1655bb7698b816011cbd1ebedbcc311110bc Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 12 Jun 2013 14:58:07 +0200 Subject: [PATCH 110/213] Restored HW cursor rotation and resolution/fullscreen switching --- CMakeLists.txt | 1 + apps/openmw/mwgui/windowmanagerimp.cpp | 3 +- apps/openmw/mwrender/renderingmanager.cpp | 4 +++ extern/sdl4ogre/cursormanager.hpp | 2 +- extern/sdl4ogre/sdlcursormanager.cpp | 39 ++++++++++------------- extern/sdl4ogre/sdlcursormanager.hpp | 4 +-- extern/sdl4ogre/sdlinputwrapper.cpp | 10 ++---- libs/openengine/ogre/renderer.cpp | 5 ++- 8 files changed, 32 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c2fbdb9b..3c115cdee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ set(OENGINE_OGRE ${LIBDIR}/openengine/ogre/fader.cpp ${LIBDIR}/openengine/ogre/particles.cpp ${LIBDIR}/openengine/ogre/selectionbuffer.cpp + ${LIBDIR}/openengine/ogre/imagerotate.cpp ) set(OENGINE_GUI ${LIBDIR}/openengine/gui/manager.cpp diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 48561936d..099a59038 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -968,8 +968,9 @@ namespace MWGui Uint8 size_y = imgSetPtr->getSize().height; Uint8 hotspot_x = imgSetPtr->getHotSpot().left; Uint8 hotspot_y = imgSetPtr->getHotSpot().top; + int rotation = imgSetPtr->getRotation(); - mCursorManager->receiveCursorInfo(name, tex, size_x, size_y, hotspot_x, hotspot_y); + mCursorManager->receiveCursorInfo(name, rotation, tex, size_x, size_y, hotspot_x, hotspot_y); } } } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e327c3c89..df5293d73 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -16,6 +16,8 @@ #include #include +#include "SDL2/SDL.h" + #include #include @@ -796,8 +798,10 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec if (x != mRendering.getWindow()->getWidth() || y != mRendering.getWindow()->getHeight()) { + SDL_SetWindowSize(mRendering.getSDLWindow(), x, y); mRendering.getWindow()->resize(x, y); } + SDL_SetWindowFullscreen(mRendering.getSDLWindow(), Settings::Manager::getBool("fullscreen", "Video") ? SDL_WINDOW_FULLSCREEN : 0); mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); } diff --git a/extern/sdl4ogre/cursormanager.hpp b/extern/sdl4ogre/cursormanager.hpp index b98d69ce3..1f52eca73 100644 --- a/extern/sdl4ogre/cursormanager.hpp +++ b/extern/sdl4ogre/cursormanager.hpp @@ -22,7 +22,7 @@ public: virtual bool cursorChanged(const std::string &name) = 0; /// \brief Follow up a cursorChanged() call with enough info to create an cursor. - virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0; + virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0; /// \brief Tell the manager when the cursor visibility changed virtual void cursorVisibilityChange(bool visible) = 0; diff --git a/extern/sdl4ogre/sdlcursormanager.cpp b/extern/sdl4ogre/sdlcursormanager.cpp index 4e24696ea..d817ce9c4 100644 --- a/extern/sdl4ogre/sdlcursormanager.cpp +++ b/extern/sdl4ogre/sdlcursormanager.cpp @@ -3,6 +3,8 @@ #include #include +#include + namespace SFO { @@ -96,37 +98,28 @@ namespace SFO _setCursorVisible(visible); } - void SDLCursorManager::receiveCursorInfo(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) + void SDLCursorManager::receiveCursorInfo(const std::string& name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) { - _createCursorFromResource(name, tex, size_x, size_y, hotspot_x, hotspot_y); + _createCursorFromResource(name, rotDegrees, tex, size_x, size_y, hotspot_x, hotspot_y); } /// \brief creates an SDL cursor from an Ogre texture - void SDLCursorManager::_createCursorFromResource(const std::string& name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) + void SDLCursorManager::_createCursorFromResource(const std::string& name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) { - //get the surfaces set up - Ogre::HardwarePixelBufferSharedPtr buffer = tex.get()->getBuffer(); - buffer.get()->lock(Ogre::HardwarePixelBuffer::HBL_READ_ONLY); - - std::string tempName = "_" + name + "_processing"; - - //we need to copy this to a temporary texture first because the cursors might be in DDS format, - //and Ogre doesn't have an interface to read DDS - Ogre::TexturePtr tempTexture = Ogre::TextureManager::getSingleton().createManual( - tempName, - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::TEX_TYPE_2D, - size_x, size_y, - 0, - Ogre::PF_FLOAT16_RGBA, - Ogre::TU_STATIC); - - tempTexture->getBuffer()->blit(buffer); - buffer->unlock(); + if (mCursorMap.find(name) != mCursorMap.end()) + return; + + std::string tempName = tex->getName() + "_rotated"; + + // we use a render target to uncompress the DDS texture + // just blitting doesn't seem to work on D3D9 + OEngine::Render::ImageRotate::rotate(tex->getName(), tempName, -rotDegrees); + + Ogre::TexturePtr resultTexture = Ogre::TextureManager::getSingleton().getByName(tempName); // now blit to memory Ogre::Image destImage; - tempTexture->convertToImage(destImage); + resultTexture->convertToImage(destImage); SDL_Surface* surf = SDL_CreateRGBSurface(0,size_x,size_y,32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF); diff --git a/extern/sdl4ogre/sdlcursormanager.hpp b/extern/sdl4ogre/sdlcursormanager.hpp index ad371f551..2cfb73a91 100644 --- a/extern/sdl4ogre/sdlcursormanager.hpp +++ b/extern/sdl4ogre/sdlcursormanager.hpp @@ -18,11 +18,11 @@ namespace SFO virtual void setEnabled(bool enabled); virtual bool cursorChanged(const std::string &name); - virtual void receiveCursorInfo(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); + virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); virtual void cursorVisibilityChange(bool visible); private: - void _createCursorFromResource(const std::string &name, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); + void _createCursorFromResource(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); void _setGUICursor(const std::string& name); diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 7977c743e..a500bc531 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -167,14 +167,8 @@ namespace SFO //eep, wrap the pointer manually if the input driver doesn't support //relative positioning natively int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE); - - if(relative) - { - if(success != 0) - { - mWrapPointer = true; - } - } + if(relative && success != 0) + mWrapPointer = true; //now remove all mouse events using the old setting from the queue SDL_PumpEvents(); diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 596d831d3..66472cda0 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -54,6 +54,9 @@ void OgreRenderer::cleanup() delete mRoot; mRoot = NULL; + // If we don't do this, the desktop resolution is not restored on exit + SDL_SetWindowFullscreen(mSDLWindow, 0); + SDL_DestroyWindow(mSDLWindow); mSDLWindow = NULL; @@ -283,7 +286,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& settings.window_x, // width, in pixels settings.window_y, // height, in pixels SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE - | (settings.fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0) + | (settings.fullscreen ? SDL_WINDOW_FULLSCREEN : 0) ); From cc077eaba67fd38ee32643c3cc157d14e39c541b Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 12 Jun 2013 15:10:04 +0200 Subject: [PATCH 111/213] Fix mouse wheel triggering a click event in mygui --- apps/openmw/mwinput/inputmanagerimp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 5d37b0050..30aa88f3b 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -463,6 +463,9 @@ namespace MWInput { mInputBinder->mousePressed (arg, id); + if (id != SDL_BUTTON_LEFT && id != SDL_BUTTON_RIGHT) + return true; // MyGUI has no use for these events + MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)); if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) From 705488ddfb932d07332bf71c9755e29a6ef04216 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 12 Jun 2013 16:07:46 +0200 Subject: [PATCH 112/213] Fix mouse movement events being discarded when there's more than one event in a frame --- apps/openmw/mwinput/inputmanagerimp.cpp | 9 ++------- apps/openmw/mwworld/player.cpp | 12 ++++++------ apps/openmw/mwworld/player.hpp | 6 +++--- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 30aa88f3b..b239765ac 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -206,7 +206,6 @@ namespace MWInput { // Tell OIS to handle all input events mInputManager->capture(); - // inject some fake mouse movement to force updating MyGUI's widget states // this shouldn't do any harm since we're moving back to the original position afterwards MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX+1), int(mMouseY+1), mMouseWheel); @@ -501,10 +500,6 @@ namespace MWInput // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor - - // Don't support the UI sensitivity slider to reduce headache - // related to when the mouse can leave the window, and what to - // do when it re-enters mMouseX = arg.x; mMouseY = arg.y; @@ -533,8 +528,8 @@ namespace MWInput // Only actually turn player when we're not in vanity mode if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot)) { - mPlayer.setYaw(x/scale); - mPlayer.setPitch(-y/scale); + mPlayer.yaw(x/scale); + mPlayer.pitch(-y/scale); } if (arg.zrel) diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index e352b4c82..cd1eb823d 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -125,20 +125,20 @@ namespace MWWorld MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Sneak, sneak); } - void Player::setYaw(float yaw) + void Player::yaw(float yaw) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[2] = yaw; + MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[2] += yaw; } - void Player::setPitch(float pitch) + void Player::pitch(float pitch) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[0] = pitch; + MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[0] += pitch; } - void Player::setRoll(float roll) + void Player::roll(float roll) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] = roll; + MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] += roll; } void Player::use() diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index fd25f749f..4660c6e9a 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -64,9 +64,9 @@ namespace MWWorld void setRunState(bool run); void setSneak(bool sneak); - void setYaw(float yaw); - void setPitch(float pitch); - void setRoll(float roll); + void yaw(float yaw); + void pitch(float pitch); + void roll(float roll); }; } #endif From 403704b92ac2b9c47c2f48a0f86225be2f99177b Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 12 Jun 2013 16:15:04 +0200 Subject: [PATCH 113/213] Use openmw.png for SDL_SetWindowIcon --- apps/openmw/engine.cpp | 1 + apps/openmw/mwrender/renderingmanager.cpp | 4 +- extern/sdl4ogre/sdlinputwrapper.cpp | 4 +- files/mygui/CMakeLists.txt | 1 + libs/openengine/ogre/renderer.cpp | 67 ++++++++++++++++++++++- libs/openengine/ogre/renderer.hpp | 6 ++ 6 files changed, 78 insertions(+), 5 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 92904b166..95f6e6e92 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -421,6 +421,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) windowSettings.window_x = settings.getInt("resolution x", "Video"); windowSettings.window_y = settings.getInt("resolution y", "Video"); windowSettings.vsync = settings.getBool("vsync", "Video"); + windowSettings.icon = "openmw.png"; std::string aa = settings.getString("antialiasing", "Video"); windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0"; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index df5293d73..bb187d8ca 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -131,7 +131,7 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b Ogre::TextureManager::getSingleton().setMemoryBudget(126*1024*1024); Ogre::MeshManager::getSingleton().setMemoryBudget(64*1024*1024); - ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); // disable unsupported effects if (!Settings::Manager::getBool("shaders", "Objects")) @@ -312,7 +312,7 @@ void RenderingManager::update (float duration, bool paused) MWWorld::Ptr player = world->getPlayer().getPlayer(); int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude; - mRendering.getFader()->setFactor(1.f-(blind / 100.f)); + mRendering.getFader()->setFactor(std::max(0.f, 1.f-(blind / 100.f))); setAmbientMode(); // player position diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index a500bc531..70a775113 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -205,8 +205,8 @@ namespace SFO SDL_GetWindowSize(mSDLWindow, &width, &height); - const int FUDGE_FACTOR_X = width / 8; - const int FUDGE_FACTOR_Y = height / 8; + const int FUDGE_FACTOR_X = width; + const int FUDGE_FACTOR_Y = height; //warp the mouse if it's about to go outside the window if(evt.x - FUDGE_FACTOR_X < 0 || evt.x + FUDGE_FACTOR_X > width diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index af695ac6c..1ec1e08cb 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -84,6 +84,7 @@ set(MYGUI_FILES smallbars.png DejaVuLGCSansMono.ttf markers.png + ../launcher/images/openmw.png ) diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 66472cda0..193e094bc 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -54,6 +54,9 @@ void OgreRenderer::cleanup() delete mRoot; mRoot = NULL; + if (mWindowIconSurface) + SDL_FreeSurface(mWindowIconSurface); + // If we don't do this, the desktop resolution is not restored on exit SDL_SetWindowFullscreen(mSDLWindow, 0); @@ -289,7 +292,6 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& | (settings.fullscreen ? SDL_WINDOW_FULLSCREEN : 0) ); - //get the native whnd struct SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); @@ -330,6 +332,13 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& mWindow = mRoot->createRenderWindow(title, settings.window_x, settings.window_y, settings.fullscreen, ¶ms); + // Set the window icon + if (settings.icon != "") + { + mWindowIconSurface = ogreTextureToSDLSurface(settings.icon); + SDL_SetWindowIcon(mSDLWindow, mWindowIconSurface); + } + // create the semi-transparent black background texture used by the GUI. // has to be created in code with TU_DYNAMIC_WRITE_ONLY param // so that it can be modified at runtime. @@ -388,3 +397,59 @@ void OgreRenderer::setFov(float fov) { mCamera->setFOVy(Degree(fov)); } + +SDL_Surface* OgreRenderer::ogreTextureToSDLSurface(const std::string& name) +{ + Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().load(name, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + if (texture.isNull()) + { + std::stringstream error; + error << "Window icon not found: " << name; + throw std::runtime_error(error.str()); + } + Ogre::Image image; + texture->convertToImage(image); + + SDL_Surface* surface = SDL_CreateRGBSurface(0,texture->getWidth(),texture->getHeight(),32,0xFF000000,0x00FF0000,0x0000FF00,0x000000FF); + + //copy the Ogre texture to an SDL surface + for(size_t x = 0; x < texture->getWidth(); ++x) + { + for(size_t y = 0; y < texture->getHeight(); ++y) + { + Ogre::ColourValue clr = image.getColourAt(x, y, 0); + + //set the pixel on the SDL surface to the same value as the Ogre texture's + int bpp = surface->format->BytesPerPixel; + /* Here p is the address to the pixel we want to set */ + Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; + Uint32 pixel = SDL_MapRGBA(surface->format, clr.r*255, clr.g*255, clr.b*255, clr.a*255); + switch(bpp) { + case 1: + *p = pixel; + break; + + case 2: + *(Uint16 *)p = pixel; + break; + + case 3: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { + p[0] = (pixel >> 16) & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = pixel & 0xff; + } else { + p[0] = pixel & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = (pixel >> 16) & 0xff; + } + break; + + case 4: + *(Uint32 *)p = pixel; + break; + } + } + } + return surface; +} diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index 60934dda6..8b73675c3 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -32,6 +32,7 @@ #endif struct SDL_Window; +struct SDL_Surface; namespace Ogre { @@ -56,6 +57,7 @@ namespace OEngine bool fullscreen; int window_x, window_y; std::string fsaa; + std::string icon; }; #if defined(__APPLE__) && !defined(__LP64__) @@ -80,6 +82,7 @@ namespace OEngine #endif Ogre::RenderWindow *mWindow; SDL_Window *mSDLWindow; + SDL_Surface *mWindowIconSurface; Ogre::SceneManager *mScene; Ogre::Camera *mCamera; Ogre::Viewport *mView; @@ -103,6 +106,8 @@ namespace OEngine std::vector mAffectorFactories; bool logging; + SDL_Surface* ogreTextureToSDLSurface(const std::string& name); + public: OgreRenderer() : mRoot(NULL) @@ -111,6 +116,7 @@ namespace OEngine , mScene(NULL) , mCamera(NULL) , mView(NULL) + , mWindowIconSurface(NULL) #ifdef ENABLE_PLUGIN_CgProgramManager , mCgPlugin(NULL) #endif From c29699487fcc2e61a9aad4df561b5fcc34881a0e Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 12 Jun 2013 17:08:02 +0200 Subject: [PATCH 114/213] forgot to add file --- libs/openengine/ogre/imagerotate.cpp | 88 ++++++++++++++++++++++++++++ libs/openengine/ogre/imagerotate.hpp | 27 +++++++++ 2 files changed, 115 insertions(+) create mode 100644 libs/openengine/ogre/imagerotate.cpp create mode 100644 libs/openengine/ogre/imagerotate.hpp diff --git a/libs/openengine/ogre/imagerotate.cpp b/libs/openengine/ogre/imagerotate.cpp new file mode 100644 index 000000000..3dd584078 --- /dev/null +++ b/libs/openengine/ogre/imagerotate.cpp @@ -0,0 +1,88 @@ +#include "imagerotate.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Ogre; +using namespace OEngine::Render; + +void ImageRotate::rotate(const std::string& sourceImage, const std::string& destImage, const float angle) +{ + Root* root = Ogre::Root::getSingletonPtr(); + + std::string destImageRot = std::string(destImage) + std::string("_rot"); + + SceneManager* sceneMgr = root->createSceneManager(ST_GENERIC); + Camera* camera = sceneMgr->createCamera("ImageRotateCamera"); + + MaterialPtr material = MaterialManager::getSingleton().create("ImageRotateMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + material->getTechnique(0)->getPass(0)->setLightingEnabled(false); + material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); + TextureUnitState* tus = material->getTechnique(0)->getPass(0)->createTextureUnitState(sourceImage); + Degree deg(angle); + tus->setTextureRotate(Radian(deg.valueRadians())); + tus->setTextureAddressingMode(TextureUnitState::TAM_BORDER); + tus->setTextureBorderColour(ColourValue(0, 0, 0, 0)); + + Rectangle2D* rect = new Rectangle2D(true); + rect->setCorners(-1.0, 1.0, 1.0, -1.0); + rect->setMaterial("ImageRotateMaterial"); + // Render the background before everything else + rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND); + + // Use infinite AAB to always stay visible + AxisAlignedBox aabInf; + aabInf.setInfinite(); + rect->setBoundingBox(aabInf); + + // Attach background to the scene + SceneNode* node = sceneMgr->getRootSceneNode()->createChildSceneNode(); + node->attachObject(rect); + + // retrieve image width and height + TexturePtr sourceTexture = TextureManager::getSingleton().getByName(sourceImage); + unsigned int width = sourceTexture->getWidth(); + unsigned int height = sourceTexture->getHeight(); + + TexturePtr destTextureRot = TextureManager::getSingleton().createManual( + destImageRot, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, + width, height, + 0, + PF_FLOAT16_RGBA, + TU_RENDERTARGET); + + RenderTarget* rtt = destTextureRot->getBuffer()->getRenderTarget(); + rtt->setAutoUpdated(false); + Viewport* vp = rtt->addViewport(camera); + vp->setOverlaysEnabled(false); + vp->setShadowsEnabled(false); + vp->setBackgroundColour(ColourValue(0,0,0,0)); + + rtt->update(); + + //copy the rotated image to a static texture + TexturePtr destTexture = TextureManager::getSingleton().createManual( + destImage, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, + width, height, + 0, + PF_FLOAT16_RGBA, + Ogre::TU_STATIC); + + destTexture->getBuffer()->blit(destTextureRot->getBuffer()); + + // remove all the junk we've created + TextureManager::getSingleton().remove(destImageRot); + MaterialManager::getSingleton().remove("ImageRotateMaterial"); + root->destroySceneManager(sceneMgr); + delete rect; +} diff --git a/libs/openengine/ogre/imagerotate.hpp b/libs/openengine/ogre/imagerotate.hpp new file mode 100644 index 000000000..a3f6d662f --- /dev/null +++ b/libs/openengine/ogre/imagerotate.hpp @@ -0,0 +1,27 @@ +#ifndef OENGINE_OGRE_IMAGEROTATE_HPP +#define OENGINE_OGRE_IMAGEROTATE_HPP + +#include + +namespace OEngine +{ +namespace Render +{ + + /// Rotate an image by certain degrees and save as file, uses the GPU + /// Make sure Ogre Root is initialised before calling + class ImageRotate + { + public: + /** + * @param source image (file name - has to exist in an resource group) + * @param name of the destination texture to save to (in memory) + * @param angle in degrees to turn + */ + static void rotate(const std::string& sourceImage, const std::string& destImage, const float angle); + }; + +} +} + +#endif From 14a2a26a5623b6c32d71a4858a129511acdfe58c Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 12 Jun 2013 20:08:55 +0200 Subject: [PATCH 115/213] Fullscreen resizing fix --- apps/openmw/mwrender/renderingmanager.cpp | 5 ++++- extern/oics/ICSPrerequisites.h | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index bb187d8ca..a60ba3060 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -796,13 +796,16 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec unsigned int x = Settings::Manager::getInt("resolution x", "Video"); unsigned int y = Settings::Manager::getInt("resolution y", "Video"); + SDL_SetWindowFullscreen(mRendering.getSDLWindow(), 0); + if (x != mRendering.getWindow()->getWidth() || y != mRendering.getWindow()->getHeight()) { SDL_SetWindowSize(mRendering.getSDLWindow(), x, y); mRendering.getWindow()->resize(x, y); } + SDL_SetWindowFullscreen(mRendering.getSDLWindow(), Settings::Manager::getBool("fullscreen", "Video") ? SDL_WINDOW_FULLSCREEN : 0); - mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); + //mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); } mWater->processChangedSettings(settings); diff --git a/extern/oics/ICSPrerequisites.h b/extern/oics/ICSPrerequisites.h index 2e107355a..52daea3f4 100644 --- a/extern/oics/ICSPrerequisites.h +++ b/extern/oics/ICSPrerequisites.h @@ -39,7 +39,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tinyxml.h" -#include "SDL_input.h" #include "SDL_keyboard.h" #include "SDL_mouse.h" #include "SDL_joystick.h" From ab3634d692a6ef3c9ee1fc87a3a6d06a0d684a9f Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 12 Jun 2013 20:13:19 +0200 Subject: [PATCH 116/213] Removed some remains of OIS --- CMakeLists.txt | 2 +- apps/openmw/CMakeLists.txt | 4 +- cmake/FindOIS.cmake | 87 -------------------------------------- 3 files changed, 2 insertions(+), 91 deletions(-) delete mode 100644 cmake/FindOIS.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c115cdee..d33dde844 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -358,7 +358,7 @@ if(DPKG_PROGRAM) SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 0c85c2b5c..47bebe78c 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -106,7 +106,6 @@ target_link_libraries(openmw ${OGRE_LIBRARIES} ${OGRE_Terrain_LIBRARY} ${OGRE_STATIC_PLUGINS} - ${OIS_LIBRARIES} ${Boost_LIBRARIES} ${OPENAL_LIBRARY} ${SOUND_INPUT_LIBRARY} @@ -114,8 +113,7 @@ target_link_libraries(openmw ${MYGUI_LIBRARIES} ${SDL2_LIBRARY} ${MYGUI_PLATFORM_LIBRARIES} - "shiny" - "shiny.OgrePlatform" + ${SHINY_LIBRARIES} "oics" "sdl4ogre" components diff --git a/cmake/FindOIS.cmake b/cmake/FindOIS.cmake deleted file mode 100644 index e0278d8a2..000000000 --- a/cmake/FindOIS.cmake +++ /dev/null @@ -1,87 +0,0 @@ -#------------------------------------------------------------------- -# This file is part of the CMake build system for OGRE -# (Object-oriented Graphics Rendering Engine) -# For the latest info, see http://www.ogre3d.org/ -# -# The contents of this file are placed in the public domain. Feel -# free to make use of it in any way you like. -#------------------------------------------------------------------- - -# - Try to find OIS -# Once done, this will define -# -# OIS_FOUND - system has OIS -# OIS_INCLUDE_DIRS - the OIS include directories -# OIS_LIBRARIES - link these to use OIS -# OIS_BINARY_REL / OIS_BINARY_DBG - DLL names (windows only) - -include(FindPkgMacros) -findpkg_begin(OIS) - -# Get path, convert backslashes as ${ENV_${var}} -getenv_path(OIS_HOME) -getenv_path(OGRE_SDK) -getenv_path(OGRE_HOME) -getenv_path(OGRE_SOURCE) -getenv_path(OGRE_DEPENDENCIES_DIR) - -# construct search paths -set(OIS_PREFIX_PATH ${OIS_HOME} ${ENV_OIS_HOME} - ${OGRE_DEPENDENCIES_DIR} ${ENV_OGRE_DEPENDENCIES_DIR} - ${OGRE_SOURCE}/iPhoneDependencies ${ENV_OGRE_SOURCE}/iPhoneDependencies - ${OGRE_SOURCE}/Dependencies ${ENV_OGRE_SOURCE}/Dependencies - ${OGRE_SDK} ${ENV_OGRE_SDK} - ${OGRE_HOME} ${ENV_OGRE_HOME}) -create_search_paths(OIS) -# redo search if prefix path changed -clear_if_changed(OIS_PREFIX_PATH - OIS_LIBRARY_FWK - OIS_LIBRARY_REL - OIS_LIBRARY_DBG - OIS_INCLUDE_DIR -) - -set(OIS_LIBRARY_NAMES OIS) -get_debug_names(OIS_LIBRARY_NAMES) - -use_pkgconfig(OIS_PKGC OIS) - -# For OIS, prefer static library over framework (important when referencing OIS source build) -set(CMAKE_FIND_FRAMEWORK "LAST") - -findpkg_framework(OIS) -if (OIS_HOME) - # OIS uses the 'includes' path for its headers in the source release, not 'include' - set(OIS_INC_SEARCH_PATH ${OIS_INC_SEARCH_PATH} ${OIS_HOME}/includes) -endif() -if (APPLE AND OIS_HOME) - # OIS source build on Mac stores libs in a different location - # Also this is for static build - set(OIS_LIB_SEARCH_PATH ${OIS_LIB_SEARCH_PATH} ${OIS_HOME}/Mac/XCode-2.2/build) -endif() -find_path(OIS_INCLUDE_DIR NAMES OIS.h HINTS ${OIS_INC_SEARCH_PATH} ${OIS_PKGC_INCLUDE_DIRS} PATH_SUFFIXES OIS) -find_library(OIS_LIBRARY_REL NAMES ${OIS_LIBRARY_NAMES} HINTS ${OIS_LIB_SEARCH_PATH} ${OIS_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" release relwithdebinfo minsizerel) -find_library(OIS_LIBRARY_DBG NAMES ${OIS_LIBRARY_NAMES_DBG} HINTS ${OIS_LIB_SEARCH_PATH} ${OIS_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" debug) -make_library_set(OIS_LIBRARY) - -if (WIN32) - set(OIS_BIN_SEARCH_PATH ${OIS_HOME}/dll ${ENV_OIS_HOME}/dll - ${OGRE_DEPENDENCIES_DIR}/bin ${ENV_OGRE_DEPENDENCIES_DIR}/bin - ${OGRE_SOURCE}/Dependencies/bin ${ENV_OGRE_SOURCE}/Dependencies/bin - ${OGRE_SDK}/bin ${ENV_OGRE_SDK}/bin - ${OGRE_HOME}/bin ${ENV_OGRE_HOME}/bin) - find_file(OIS_BINARY_REL NAMES "OIS.dll" HINTS ${OIS_BIN_SEARCH_PATH} - PATH_SUFFIXES "" release relwithdebinfo minsizerel) - find_file(OIS_BINARY_DBG NAMES "OIS_d.dll" HINTS ${OIS_BIN_SEARCH_PATH} - PATH_SUFFIXES "" debug ) -endif() -mark_as_advanced(OIS_BINARY_REL OIS_BINARY_DBG) - - -findpkg_finish(OIS) - -# add parent of OIS folder to support OIS/OIS.h -add_parent_dir(OIS_INCLUDE_DIRS OIS_INCLUDE_DIR) - -# Reset framework finding -set(CMAKE_FIND_FRAMEWORK "FIRST") From fcf35d3871e722fcb6b304b0cc9f4a3360e812bc Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 12 Jun 2013 20:27:55 +0200 Subject: [PATCH 117/213] Removed the UI cursor sensitivity slider --- apps/openmw/mwgui/settingswindow.cpp | 7 ------- apps/openmw/mwgui/settingswindow.hpp | 1 - files/mygui/openmw_settings_window.layout | 24 ++++------------------- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 413171dd4..edce00d5d 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -126,7 +126,6 @@ namespace MWGui getWidget(mControlsBox, "ControlsBox"); getWidget(mResetControlsButton, "ResetControlsButton"); getWidget(mInvertYButton, "InvertYButton"); - getWidget(mUISensitivitySlider, "UISensitivitySlider"); getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); getWidget(mRefractionButton, "RefractionButton"); @@ -240,11 +239,7 @@ namespace MWGui float cameraSens = (Settings::Manager::getFloat("camera sensitivity", "Input")-0.2)/(5.0-0.2); mCameraSensitivitySlider->setScrollPosition (cameraSens * (mCameraSensitivitySlider->getScrollRange()-1)); - float uiSens = (Settings::Manager::getFloat("ui sensitivity", "Input")-0.2)/(5.0-0.2); - mUISensitivitySlider->setScrollPosition (uiSens * (mUISensitivitySlider->getScrollRange()-1)); mCameraSensitivitySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mUISensitivitySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mInvertYButton->setCaptionWithReplacing(Settings::Manager::getBool("invert y axis", "Input") ? "#{sOn}" : "#{sOff}"); @@ -529,8 +524,6 @@ namespace MWGui Settings::Manager::setFloat("footsteps volume", "Sound", val); else if (scroller == mMusicVolumeSlider) Settings::Manager::setFloat("music volume", "Sound", val); - else if (scroller == mUISensitivitySlider) - Settings::Manager::setFloat("ui sensitivity", "Input", (1-val) * 0.2 + val * 5.f); else if (scroller == mCameraSensitivitySlider) Settings::Manager::setFloat("camera sensitivity", "Input", (1-val) * 0.2 + val * 5.f); diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 6dcef2422..20e9907d9 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -71,7 +71,6 @@ namespace MWGui MyGUI::ScrollView* mControlsBox; MyGUI::Button* mResetControlsButton; MyGUI::Button* mInvertYButton; - MyGUI::ScrollBar* mUISensitivitySlider; MyGUI::ScrollBar* mCameraSensitivitySlider; void onOkButtonClicked(MyGUI::Widget* _sender); diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 77d14d0f6..3c65bb690 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -114,33 +114,17 @@
- - - - - - - - - - - - - - - - - + - + - + - + From aac3ada14bb2f266a650e8e5a018c24ff8f8507e Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Thu, 13 Jun 2013 00:50:07 -0500 Subject: [PATCH 118/213] Use mousewheel to turn book pages. --- apps/openmw/mwgui/bookwindow.cpp | 41 +++++++++++++++---------- apps/openmw/mwgui/bookwindow.hpp | 3 +- apps/openmw/mwinput/inputmanagerimp.cpp | 10 ++++++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index 3b5deb5ac..672503154 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -130,26 +130,12 @@ namespace MWGui void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender) { - if ((mCurrentPage+1)*2 < mPages.size()) - { - MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0); - - ++mCurrentPage; - - updatePages(); - } + nextPage(); } void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender) { - if (mCurrentPage > 0) - { - MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0); - - --mCurrentPage; - - updatePages(); - } + prevPage(); } void BookWindow::updatePages() @@ -194,5 +180,28 @@ namespace MWGui if (button->getAlign().isRight()) button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0)); } + + void BookWindow::nextPage() + { + if ((mCurrentPage+1)*2 < mPages.size()) + { + MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0); + + ++mCurrentPage; + + updatePages(); + } + } + void BookWindow::prevPage() + { + if (mCurrentPage > 0) + { + MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0); + + --mCurrentPage; + + updatePages(); + } + } } diff --git a/apps/openmw/mwgui/bookwindow.hpp b/apps/openmw/mwgui/bookwindow.hpp index c6ea486d4..ef87dd9c4 100644 --- a/apps/openmw/mwgui/bookwindow.hpp +++ b/apps/openmw/mwgui/bookwindow.hpp @@ -16,7 +16,8 @@ namespace MWGui void open(MWWorld::Ptr book); void setTakeButtonShow(bool show); - + void nextPage(); + void prevPage(); void setInventoryAllowed(bool allowed); protected: diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 00c520de9..f60ec6797 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -25,6 +25,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwgui/bookwindow.hpp" namespace MWInput { @@ -552,6 +553,15 @@ namespace MWInput if (arg.state.Z.rel) MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.state.Z.rel); } + + //if the player is reading a book and flicking the mouse wheel + if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Book && arg.state.Z.rel) + { + if (arg.state.Z.rel < 0) + MWBase::Environment::get().getWindowManager()->getBookWindow()->nextPage(); + else + MWBase::Environment::get().getWindowManager()->getBookWindow()->prevPage(); + } return true; } From 9d4ecc3e7351a37141ff0597a0d1588f5e3d6057 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Thu, 13 Jun 2013 00:52:26 -0500 Subject: [PATCH 119/213] replace tabs with spaces. --- apps/openmw/mwgui/bookwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index 672503154..f24922e23 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -183,7 +183,7 @@ namespace MWGui void BookWindow::nextPage() { - if ((mCurrentPage+1)*2 < mPages.size()) + if ((mCurrentPage+1)*2 < mPages.size()) { MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0); @@ -194,7 +194,7 @@ namespace MWGui } void BookWindow::prevPage() { - if (mCurrentPage > 0) + if (mCurrentPage > 0) { MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0); From 088080555991b49d05c7f9cc93bd7edee8b6dd93 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 13 Jun 2013 12:13:40 +0200 Subject: [PATCH 120/213] Minor cleanup --- apps/openmw/mwgui/windowmanagerimp.cpp | 6 ------ apps/openmw/mwinput/inputmanagerimp.cpp | 4 +--- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 099a59038..17c23699f 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -13,12 +13,6 @@ #include -#include -#include - -#include "../mwbase/environment.hpp" -#include "../mwbase/mechanicsmanager.hpp" - #include "../mwbase/inputmanager.hpp" #include "../mwworld/class.hpp" diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index b239765ac..203123d5b 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -562,9 +562,7 @@ namespace MWInput if (MyGUI::InputManager::getInstance ().isModalAny()) return; - if (mWindows.isGuiMode () && (mWindows.getMode () == MWGui::GM_MainMenu || mWindows.getMode () == MWGui::GM_Settings)) - mWindows.popGuiMode(); - else if (mWindows.isGuiMode () && mWindows.getMode () == MWGui::GM_Video) + if (mWindows.isGuiMode () && mWindows.getMode () == MWGui::GM_Video) MWBase::Environment::get().getWorld ()->stopVideo (); else if (mWindows.containsMode(MWGui::GM_MainMenu)) mWindows.popGuiMode(); From e5ddaaf6768095a1ce62e3029cea187c145c089e Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Thu, 13 Jun 2013 11:17:34 -0500 Subject: [PATCH 121/213] Fix wrong indenting from my last commits. --- apps/openmw/mwgui/journalwindow.cpp | 5 ++--- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 89ee42934..ab8dc1584 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -213,7 +213,6 @@ namespace void close() { - mModel->unload (); getPage (LeftBookPage)->showPage (Book (), 0); @@ -433,7 +432,7 @@ namespace void notifyClose(MyGUI::Widget* _sender) { - MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); MWBase::Environment::get().getWindowManager ()->popGuiMode (); } @@ -472,4 +471,4 @@ namespace MWGui::JournalWindow * MWGui::JournalWindow::create (JournalViewModel::Ptr Model) { return new JournalWindowImpl (Model); -} \ No newline at end of file +} diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index cb4f08b9c..1f1dc53b0 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -668,7 +668,7 @@ namespace MWInput if(gameMode && MWBase::Environment::get().getWindowManager ()->getJournalAllowed()) { - MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0); + MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0); mWindows.pushGuiMode(MWGui::GM_Journal); } else if(mWindows.getMode() == MWGui::GM_Journal) From adf54cb735bc13d1363dbfd67a1b35a0477e6ba1 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 15 Jun 2013 13:54:24 +0400 Subject: [PATCH 122/213] SDL2 input: compilation fixed --- libs/openengine/ogre/renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 193e094bc..f27858a78 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -308,7 +308,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& // Windows code winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.win.window); break; -#elif MACOS +#elif __APPLE__ case SDL_SYSWM_COCOA: //required to make OGRE play nice with our window params.insert(std::make_pair("macAPI", "cocoa")); From 3fded2d8bf4c8f0e8eb78cc3487512acc0057ee0 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 15 Jun 2013 13:55:09 +0400 Subject: [PATCH 123/213] Removed custom Carbon message pump --- libs/openengine/ogre/renderer.cpp | 51 ------------------------------- libs/openengine/ogre/renderer.hpp | 21 ------------- 2 files changed, 72 deletions(-) diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index f27858a78..c27d8871a 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -23,29 +23,9 @@ #include #include -#if defined(__APPLE__) && !defined(__LP64__) -#include -#endif - using namespace Ogre; using namespace OEngine::Render; - -#if defined(__APPLE__) && !defined(__LP64__) - -CustomRoot::CustomRoot(const Ogre::String& pluginFileName, - const Ogre::String& configFileName, - const Ogre::String& logFileName) -: Ogre::Root(pluginFileName, configFileName, logFileName) -{} - -bool CustomRoot::isQueuedEnd() const -{ - return mQueuedEnd; -} - -#endif - void OgreRenderer::cleanup() { delete mFader; @@ -68,34 +48,7 @@ void OgreRenderer::cleanup() void OgreRenderer::start() { - //TODO: Check if we still need to do this if we're using SDL's - //message pump -#if defined(__APPLE__) && !defined(__LP64__) - // OSX Carbon Message Pump - do { - EventRef event = NULL; - EventTargetRef targetWindow; - targetWindow = GetEventDispatcherTarget(); - - // If we are unable to get the target then we no longer care about events. - if (!targetWindow) return; - - // Grab the next event while possible - while (ReceiveNextEvent(0, NULL, kEventDurationNoWait, true, &event) == noErr) - { - // Dispatch the event - SendEventToEventTarget(event, targetWindow); - ReleaseEvent(event); - } - - if (!mRoot->renderOneFrame()) { - break; - } - - } while (!mRoot->isQueuedEnd()); -#else mRoot->startRendering(); -#endif } void OgreRenderer::loadPlugins() @@ -188,11 +141,7 @@ void OgreRenderer::configure(const std::string &logPath, // Disable logging log->setDebugOutputEnabled(false); -#if defined(__APPLE__) && !defined(__LP64__) - mRoot = new CustomRoot("", "", ""); -#else mRoot = new Root("", "", ""); -#endif #if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX) loadPlugins(); diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index 8b73675c3..0cd0e74e8 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -27,18 +27,12 @@ #include "OgreTexture.h" #include -#if defined(__APPLE__) && !defined(__LP64__) -#include -#endif - struct SDL_Window; struct SDL_Surface; namespace Ogre { -#if !defined(__APPLE__) || defined(__LP64__) class Root; -#endif class RenderWindow; class SceneManager; class Camera; @@ -60,26 +54,11 @@ namespace OEngine std::string icon; }; -#if defined(__APPLE__) && !defined(__LP64__) - class CustomRoot : public Ogre::Root { - public: - bool isQueuedEnd() const; - - CustomRoot(const Ogre::String& pluginFileName = "plugins.cfg", - const Ogre::String& configFileName = "ogre.cfg", - const Ogre::String& logFileName = "Ogre.log"); - }; -#endif - class Fader; class OgreRenderer { -#if defined(__APPLE__) && !defined(__LP64__) - CustomRoot *mRoot; -#else Ogre::Root *mRoot; -#endif Ogre::RenderWindow *mWindow; SDL_Window *mSDLWindow; SDL_Surface *mWindowIconSurface; From 6abb7a18b0ef96980a97528c13ada45dabaff470 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 15 Jun 2013 14:40:18 +0400 Subject: [PATCH 124/213] SDL2 input: seems to work on OS X, has some input issues though --- CMakeLists.txt | 5 +++++ libs/openengine/ogre/osx_utils.h | 14 ++++++++++++++ libs/openengine/ogre/osx_utils.mm | 16 ++++++++++++++++ libs/openengine/ogre/renderer.cpp | 8 ++++++-- 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 libs/openengine/ogre/osx_utils.h create mode 100644 libs/openengine/ogre/osx_utils.mm diff --git a/CMakeLists.txt b/CMakeLists.txt index d33dde844..e8cfdcbdf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,11 @@ set(OENGINE_OGRE ${LIBDIR}/openengine/ogre/selectionbuffer.cpp ${LIBDIR}/openengine/ogre/imagerotate.cpp ) + +if (APPLE) + set(OENGINE_OGRE ${OENGINE_OGRE} ${LIBDIR}/openengine/ogre/osx_utils.mm) +endif () + set(OENGINE_GUI ${LIBDIR}/openengine/gui/manager.cpp ) diff --git a/libs/openengine/ogre/osx_utils.h b/libs/openengine/ogre/osx_utils.h new file mode 100644 index 000000000..f651db604 --- /dev/null +++ b/libs/openengine/ogre/osx_utils.h @@ -0,0 +1,14 @@ +#ifndef OENGINE_OGRE_OSX_UTILS_H +#define OENGINE_OGRE_OSX_UTILS_H + +#include + +namespace OEngine { +namespace Render { + +extern unsigned long WindowContentViewHandle(SDL_SysWMinfo &info); + +} +} + +#endif diff --git a/libs/openengine/ogre/osx_utils.mm b/libs/openengine/ogre/osx_utils.mm new file mode 100644 index 000000000..7e5660146 --- /dev/null +++ b/libs/openengine/ogre/osx_utils.mm @@ -0,0 +1,16 @@ +#include "osx_utils.h" + +#import + +namespace OEngine { +namespace Render { + +unsigned long WindowContentViewHandle(SDL_SysWMinfo &info) +{ + NSWindow *window = info.info.cocoa.window; + NSView *view = [window contentView]; + return (unsigned long)view; +} + +} +} diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index c27d8871a..e3bba8bfa 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -23,6 +23,10 @@ #include #include +#ifdef __MACOSX__ +#include "osx_utils.h" +#endif + using namespace Ogre; using namespace OEngine::Render; @@ -257,13 +261,13 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& // Windows code winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.win.window); break; -#elif __APPLE__ +#elif __MACOSX__ case SDL_SYSWM_COCOA: //required to make OGRE play nice with our window params.insert(std::make_pair("macAPI", "cocoa")); params.insert(std::make_pair("macAPICocoaUseNSView", "true")); - winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.cocoa.window); + winHandle = Ogre::StringConverter::toString(WindowContentViewHandle(wmInfo)); break; #else case SDL_SYSWM_X11: From 5984a158462b0d7a7763629f6ec15fe428f75c40 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 15 Jun 2013 14:47:33 +0400 Subject: [PATCH 125/213] We don't need Carbon on OS X anymore --- apps/esmtool/CMakeLists.txt | 5 ----- apps/openmw/CMakeLists.txt | 3 +-- apps/openmw/mwinput/inputmanagerimp.cpp | 10 ---------- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/apps/esmtool/CMakeLists.txt b/apps/esmtool/CMakeLists.txt index 5c588fb29..1d0026215 100644 --- a/apps/esmtool/CMakeLists.txt +++ b/apps/esmtool/CMakeLists.txt @@ -17,11 +17,6 @@ target_link_libraries(esmtool components ) -#if (APPLE) -# find_library(CARBON_FRAMEWORK Carbon) -# target_link_libraries(openmw ${CARBON_FRAMEWORK}) -#endif (APPLE) - if (BUILD_WITH_CODE_COVERAGE) add_definitions (--coverage) target_link_libraries(esmtool gcov) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 47bebe78c..ddb08f0b0 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -131,10 +131,9 @@ endif() if(APPLE) - find_library(CARBON_FRAMEWORK Carbon) find_library(COCOA_FRAMEWORK Cocoa) find_library(IOKIT_FRAMEWORK IOKit) - target_link_libraries(openmw ${CARBON_FRAMEWORK} ${COCOA_FRAMEWORK} ${IOKIT_FRAMEWORK}) + target_link_libraries(openmw ${COCOA_FRAMEWORK} ${IOKIT_FRAMEWORK}) if (FFMPEG_FOUND) find_library(COREVIDEO_FRAMEWORK CoreVideo) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 203123d5b..669957c4c 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -1,9 +1,5 @@ #include "inputmanagerimp.hpp" -#if defined(__APPLE__) && !defined(__LP64__) -#include -#endif - #include #include @@ -56,12 +52,6 @@ namespace MWInput , mOverencumberedMessageDelay(0.f) , mAlwaysRunActive(false) { -#if defined(__APPLE__) && !defined(__LP64__) - // Give the application window focus to receive input events - ProcessSerialNumber psn = { 0, kCurrentProcess }; - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - SetFrontProcess(&psn); -#endif Ogre::RenderWindow* window = ogre.getWindow (); From 9807eacb5866966d64ae053c0f9b3d9eefbb680f Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sat, 15 Jun 2013 15:17:29 +0400 Subject: [PATCH 126/213] Removed obsolete OIS workaround --- apps/openmw/mwinput/inputmanagerimp.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 669957c4c..6098ff90b 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -420,16 +420,6 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->enterPressed(); } - //TODO: Check if we need this with SDL - /* -#ifdef __APPLE__ // filter \016 symbol for F-keys on OS X - if ((arg.key >= SDLK_F1 && arg.key <= SDLK_F10) || - (arg.key >= SDLK_F11 && arg.key <= SDLK_F15)) { - text = 0; - } -#endif - */ - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), text); From 4fb32f7f056bd38e83ea9cb7d6c69468bea6843b Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 15 Jun 2013 13:22:29 +0200 Subject: [PATCH 127/213] Moved window resize messages to sdlinputwrapper --- apps/openmw/engine.cpp | 2 ++ apps/openmw/mwinput/inputmanagerimp.cpp | 8 ++++---- extern/sdl4ogre/sdlinputwrapper.cpp | 16 +++++++++++++++- extern/sdl4ogre/sdlinputwrapper.hpp | 3 ++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 95f6e6e92..e78162c29 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -136,6 +136,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) void OMW::Engine::handleSDLMessages() { + /* //Pump messages since the last frame const int max_events = 20; SDL_Event events[max_events]; @@ -174,6 +175,7 @@ void OMW::Engine::handleSDLMessages() //user requested a quit, break out. mOgre->getRoot()->queueEndRendering(); } + */ } OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 203123d5b..b9d0afe72 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -65,7 +65,7 @@ namespace MWInput Ogre::RenderWindow* window = ogre.getWindow (); - mInputManager = new SFO::InputWrapper(mOgre.getSDLWindow()); + mInputManager = new SFO::InputWrapper(mOgre.getSDLWindow(), mOgre.getWindow()); mInputManager->setMouseEventCallback (this); mInputManager->setKeyboardEventCallback (this); mInputManager->setWindowEventCallback(this); @@ -912,9 +912,9 @@ namespace MWInput void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control , SDL_Keycode key, ICS::Control::ControlChangingDirection direction) { - //Disallow binding escape key, and unassigned keys - if(key==OIS::KC_ESCAPE || key==OIS::KC_UNASSIGNED) - return + //Disallow binding escape key + if(key==SDLK_ESCAPE) + return; clearAllBindings(control); ICS::DetectingBindingListener::keyBindingDetected (ICS, control, key, direction); diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 70a775113..7cc7820f9 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -16,8 +16,9 @@ namespace SFO { /// \brief General purpose wrapper for OGRE applications around SDL's event /// queue, mostly used for handling input-related events. - InputWrapper::InputWrapper(SDL_Window* window) : + InputWrapper::InputWrapper(SDL_Window* window, Ogre::RenderWindow* ogreWindow) : mSDLWindow(window), + mOgreWindow(ogreWindow), mOwnWindow(false), mWarpCompensate(false), mMouseRelative(false), @@ -98,6 +99,9 @@ namespace SFO void InputWrapper::capture() { SDL_Event evt; + bool resize=false; + size_t size_x = 0; + size_t size_y = 0; while(SDL_PollEvent(&evt)) { switch(evt.type) @@ -128,8 +132,18 @@ namespace SFO case SDL_KEYUP: mKeyboardListener->keyReleased(evt.key); break; + case SDL_WINDOWEVENT_RESIZED: + resize = true; + size_x = evt.window.data1; + size_y = evt.window.data2; + break; + case SDL_QUIT: + Ogre::Root::getSingleton().queueEndRendering(); + break; } } + if (resize) + mOgreWindow->resize(size_x, size_y); } bool InputWrapper::isModifierHeld(int mod) diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index 257699a64..f84ebcacc 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -16,7 +16,7 @@ namespace SFO class InputWrapper { public: - InputWrapper(SDL_Window *window=NULL); + InputWrapper(SDL_Window *window, Ogre::RenderWindow* ogreWindow); ~InputWrapper(); //void initFromRenderWindow(Ogre::RenderWindow* win); @@ -65,6 +65,7 @@ namespace SFO Sint32 mMouseY; SDL_Window* mSDLWindow; + Ogre::RenderWindow* mOgreWindow; bool mOwnWindow; }; From 700d55f1fba9e4f9eebf5d67aa099cf38d397815 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 15 Jun 2013 06:40:18 -0500 Subject: [PATCH 128/213] Fixed / implemented missing features for RecordStatusDelegate Implemented updating editor application from preferences menu, loading settings when editor loads, adding Record Status Display prefernce. Fixed multiple bugs, made changes to CSM(V)Settings classes to make implementing new prefrences easier. Rewrote CSMSettings::UserSettings to retain last-loaded settings. Adjusted icon position in Record Status column Capitalized status text Added delegate to referenceables table --- apps/opencs/CMakeLists.txt | 5 +- .../model/settings/settingcontainer.hpp | 2 - apps/opencs/model/settings/settingsitem.hpp | 8 +- apps/opencs/model/settings/usersettings.cpp | 187 +++++++++++++----- apps/opencs/model/settings/usersettings.hpp | 23 ++- apps/opencs/model/world/refidcollection.cpp | 4 +- apps/opencs/view/doc/subview.cpp | 5 + apps/opencs/view/doc/subview.hpp | 3 +- apps/opencs/view/doc/view.cpp | 20 +- apps/opencs/view/doc/view.hpp | 6 +- apps/opencs/view/doc/viewmanager.cpp | 14 +- apps/opencs/view/doc/viewmanager.hpp | 2 + apps/opencs/view/settings/abstractpage.cpp | 16 +- apps/opencs/view/settings/abstractpage.hpp | 8 +- apps/opencs/view/settings/blankpage.cpp | 5 +- apps/opencs/view/settings/customblock.cpp | 12 +- apps/opencs/view/settings/customblock.hpp | 4 +- apps/opencs/view/settings/editorpage.cpp | 158 +++------------ apps/opencs/view/settings/editorpage.hpp | 28 +-- apps/opencs/view/settings/groupblock.cpp | 14 +- apps/opencs/view/settings/groupblock.hpp | 2 +- apps/opencs/view/settings/proxyblock.cpp | 4 +- apps/opencs/view/settings/proxyblock.hpp | 2 +- apps/opencs/view/settings/samplepage.cpp | 159 +++++++++++++++ apps/opencs/view/settings/samplepage.hpp | 28 +++ apps/opencs/view/settings/toggleblock.cpp | 24 +-- apps/opencs/view/settings/toggleblock.hpp | 4 +- .../view/settings/usersettingsdialog.cpp | 88 +++------ .../view/settings/usersettingsdialog.hpp | 17 +- .../view/world/recordstatusdelegate.cpp | 33 +++- .../view/world/recordstatusdelegate.hpp | 4 +- apps/opencs/view/world/table.cpp | 15 +- apps/opencs/view/world/table.hpp | 3 + apps/opencs/view/world/tablesubview.cpp | 9 +- apps/opencs/view/world/tablesubview.hpp | 4 +- apps/opencs/view/world/util.hpp | 6 + 36 files changed, 579 insertions(+), 347 deletions(-) create mode 100644 apps/opencs/view/settings/samplepage.cpp create mode 100644 apps/opencs/view/settings/samplepage.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index d30c92350..85b5ba3b6 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -57,11 +57,11 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world - table tablesubview scriptsubview + table tablesubview scriptsubview util ) opencs_units_noqt (view/world - dialoguesubview util subviews enumdelegate vartypedelegate scripthighlighter recordstatusdelegate + dialoguesubview subviews enumdelegate vartypedelegate scripthighlighter recordstatusdelegate ) @@ -78,6 +78,7 @@ opencs_units (view/settings proxyblock abstractwidget usersettingsdialog + samplepage editorpage ) diff --git a/apps/opencs/model/settings/settingcontainer.hpp b/apps/opencs/model/settings/settingcontainer.hpp index eb264248d..60f4eecad 100644 --- a/apps/opencs/model/settings/settingcontainer.hpp +++ b/apps/opencs/model/settings/settingcontainer.hpp @@ -18,8 +18,6 @@ namespace CSMSettings explicit SettingContainer (QObject *parent = 0); explicit SettingContainer (const QString &value, QObject *parent = 0); - virtual QString getName() const {return "";} - void insert (const QString &value); void update (const QString &value, int index = 0); diff --git a/apps/opencs/model/settings/settingsitem.hpp b/apps/opencs/model/settings/settingsitem.hpp index 8be05a4c7..9c5ed02af 100644 --- a/apps/opencs/model/settings/settingsitem.hpp +++ b/apps/opencs/model/settings/settingsitem.hpp @@ -12,7 +12,6 @@ namespace CSMSettings QStringPair *mValuePair; QStringList *mValueList; bool mIsMultiValue; - QString mName; QString mDefaultValue; public: @@ -20,8 +19,10 @@ namespace CSMSettings const QString& defaultValue, QObject *parent = 0) : SettingContainer(defaultValue, parent), mIsMultiValue (isMultiValue), mValueList (0), - mName (name), mValuePair (0), mDefaultValue (defaultValue) - {} + mValuePair (0), mDefaultValue (defaultValue) + { + QObject::setObjectName(name); + } bool updateItem (const QStringList *values); bool updateItem (const QString &value); @@ -33,7 +34,6 @@ namespace CSMSettings inline QStringPair *getValuePair() { return mValuePair; } inline void setValuePair (QStringPair valuePair) { mValuePair = new QStringPair(valuePair); } - inline QString getName () const { return mName; } inline bool isMultivalue () { return mIsMultiValue; } void setDefaultValue (const QString &value); diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index aabda86b3..faaa2509b 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -7,12 +7,15 @@ #include #include #include +#include #include #include "settingcontainer.hpp" #include + +#include /** * Workaround for problems with whitespaces in paths in older versions of Boost library */ @@ -29,47 +32,67 @@ namespace boost } /* namespace boost */ #endif /* (BOOST_VERSION <= 104600) */ - CSMSettings::UserSettings::UserSettings() { mUserSettingsInstance = this; + + mReadWriteMessage = QObject::tr("
Could not open or create file for writing

\ + Please make sure you have the right permissions and try again.
"); + + mReadOnlyMessage = QObject::tr("
Could not open file for reading

\ + Please make sure you have the right permissions and try again.
"); } CSMSettings::UserSettings::~UserSettings() { } -QFile *CSMSettings::UserSettings::openFile (const QString &filename) +QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, bool isReadOnly) { - QFile *file = new QFile(filename); + QFile *file = new QFile(filePath); + + QIODevice::OpenMode openFlags; - bool success = (file->open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) ; + if (isReadOnly) + openFlags = QIODevice::ReadOnly | QIODevice::Text; + else + openFlags = QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate; - if (!success) + if (!(file->open(openFlags))) { // File cannot be opened or created QMessageBox msgBox; - msgBox.setWindowTitle(QObject::tr("Error writing OpenMW configuration file")); + msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error")); msgBox.setIcon(QMessageBox::Critical); msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(QObject::tr("
Could not open or create %0 for writing

\ - Please make sure you have the right permissions \ - and try again.
").arg(file->fileName())); + + QString fileMessage = QObject::tr("
File: %0").arg(file->fileName()); + + if (!isReadOnly) + msgBox.setText (mReadWriteMessage + fileMessage); + else + msgBox.setText (mReadOnlyMessage + fileMessage); + msgBox.exec(); delete file; file = 0; } - return file; + QTextStream *stream = 0; + + if (file) + { + stream = new QTextStream(file); + stream->setCodec(QTextCodec::codecForName("UTF-8")); + } + + return stream; + } -bool CSMSettings::UserSettings::writeFile(QFile *file, QMap &settings) +bool CSMSettings::UserSettings::writeFile(QMap &settings) { - if (!file) - return false; - - QTextStream stream(file); - stream.setCodec(QTextCodec::codecForName("UTF-8")); + QTextStream *stream = openFileStream(mPaths.back()); QList keyList = settings.keys(); @@ -77,61 +100,121 @@ bool CSMSettings::UserSettings::writeFile(QFile *file, QMapgetName() << " = " << item->getValue() << '\n'; + *stream << item->objectName() << " = " << item->getValue() << '\n'; } - file->close(); + stream->device()->close(); return true; } -void CSMSettings::UserSettings::getSettings(QTextStream &stream, SectionMap §ions) +const CSMSettings::SectionMap &CSMSettings::UserSettings::getSettings() { - //looks for a square bracket, "'\\[" - //that has one or more "not nothing" in it, "([^]]+)" - //and is closed with a square bracket, "\\]" - - QRegExp sectionRe("^\\[([^]]+)\\]"); + return mSectionSettings; +} - //Find any character(s) that is/are not equal sign(s), "[^=]+" - //followed by an optional whitespace, an equal sign, and another optional whirespace, "\\s*=\\s*" - //and one or more periods, "(.+)" +void CSMSettings::UserSettings::loadFromFile(const QString &filePath) +{ + if (filePath.isEmpty()) + return; - QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$"); + mSectionSettings.clear(); - CSMSettings::SettingMap *settings = 0; - QString section = "none"; + QTextStream *stream = openFileStream (filePath, true); - while (!stream.atEnd()) + if (stream) { - QString line = stream.readLine().simplified(); + //looks for a square bracket, "'\\[" + //that has one or more "not nothing" in it, "([^]]+)" + //and is closed with a square bracket, "\\]" - if (line.isEmpty() || line.startsWith("#")) - continue; + QRegExp sectionRe("^\\[([^]]+)\\]"); - //if a section is found, push it onto a new QStringList - //and push the QStringList onto - if (sectionRe.exactMatch(line)) - { - //add the previous section's settings to the member map - if (settings) - sections.insert(section, settings); - - //save new section and create a new list - section = sectionRe.cap(1); - settings = new SettingMap; - continue; - } + //Find any character(s) that is/are not equal sign(s), "[^=]+" + //followed by an optional whitespace, an equal sign, and another optional whitespace, "\\s*=\\s*" + //and one or more periods, "(.+)" + + QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$"); - if (keyRe.indexIn(line) != -1) + CSMSettings::SettingMap *settings = 0; + QString section = "none"; + + while (!stream->atEnd()) { - SettingContainer *sc = new SettingContainer (keyRe.cap(2).simplified()); - (*settings)[keyRe.cap(1).simplified()] = sc; + QString line = stream->readLine().simplified(); + + if (line.isEmpty() || line.startsWith("#")) + continue; + + //if a section is found, push it onto a new QStringList + //and push the QStringList onto + if (sectionRe.exactMatch(line)) + { + //add the previous section's settings to the member map + if (settings) + mSectionSettings.insert(section, settings); + + //save new section and create a new list + section = sectionRe.cap(1); + settings = new SettingMap; + continue; + } + + if (keyRe.indexIn(line) != -1) + { + SettingContainer *sc = new SettingContainer (keyRe.cap(2).simplified()); + sc->setObjectName(keyRe.cap(1).simplified()); + (*settings)[keyRe.cap(1).simplified()] = sc; + } + } + mSectionSettings.insert(section, settings); + } + + stream->device()->close(); + + return; +} + +void CSMSettings::UserSettings::loadSettings (const QString &fileName) +{ + if (mPaths.count() == 0) + { + mPaths.append(QString::fromStdString(mCfgMgr.getGlobalPath().string()) + fileName); + mPaths.append(QString::fromStdString(mCfgMgr.getLocalPath().string()) + fileName); + mPaths.append(QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName); + } + + foreach (const QString &path, mPaths) + { + qDebug() << "Loading config file:" << qPrintable(path); + loadFromFile(path); + } +} + +void CSMSettings::UserSettings::updateSettings (const QString §ionName, const QString &settingName) +{ + SettingMap *settings = mSectionSettings[sectionName]; + + if (!settings) + return; + + SettingContainer *setting = 0; + + if (settingName.isEmpty()) + { + foreach (setting, *settings) + emit signalUpdateEditorSetting (setting->objectName(), setting->getValue()); + } + else + { + setting = (*settings)[settingName]; + + if (setting) + emit signalUpdateEditorSetting (setting->objectName(), setting->getValue()); } - sections.insert(section, settings); } diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 343702eda..3a7bbd1eb 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -10,6 +10,10 @@ #include "support.hpp" +#ifndef Q_MOC_RUN +#include +#endif + namespace Files { typedef std::vector PathContainer; struct ConfigurationManager;} @@ -22,6 +26,14 @@ namespace CSMSettings { Q_OBJECT + SectionMap mSectionSettings; + UserSettings *mUserSettingsInstance; + QStringList mPaths; + Files::ConfigurationManager mCfgMgr; + + QString mReadOnlyMessage; + QString mReadWriteMessage; + public: static UserSettings &instance() @@ -31,19 +43,22 @@ namespace CSMSettings { return instance; } - QFile *openFile (const QString &); - bool writeFile(QFile *file, QMap §ions); - void getSettings (QTextStream &stream, SectionMap &settings); + bool writeFile(QMap §ions); + const SectionMap &getSettings (); + void updateSettings (const QString §ionName, const QString &settingName = ""); + void loadSettings (const QString &fileName); private: - UserSettings *mUserSettingsInstance; UserSettings(); ~UserSettings(); UserSettings (UserSettings const &); //not implemented void operator= (UserSettings const &); //not implemented + QTextStream *openFileStream (const QString &filePath, bool isReadOnly = false); + void loadFromFile (const QString &filePath = ""); + signals: void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue); diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index e11fe0fc8..2bb8d07b3 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -39,7 +39,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); baseColumns.mId = &mColumns.back(); - mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, + mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_RecordState, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); baseColumns.mModified = &mColumns.back(); mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer, @@ -537,4 +537,4 @@ void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, Univers int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const { return mData.getAppendIndex (type); -} \ No newline at end of file +} diff --git a/apps/opencs/view/doc/subview.cpp b/apps/opencs/view/doc/subview.cpp index affada012..731adabb3 100644 --- a/apps/opencs/view/doc/subview.cpp +++ b/apps/opencs/view/doc/subview.cpp @@ -1,5 +1,6 @@ #include "subview.hpp" + CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id) { /// \todo add a button to the title bar that clones this sub view @@ -15,3 +16,7 @@ CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const { return mUniversalId; } + +void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QString &settingValue) +{ +} diff --git a/apps/opencs/view/doc/subview.hpp b/apps/opencs/view/doc/subview.hpp index 985c5eb3c..280a2a487 100644 --- a/apps/opencs/view/doc/subview.hpp +++ b/apps/opencs/view/doc/subview.hpp @@ -35,6 +35,7 @@ namespace CSVDoc CSMWorld::UniversalId getUniversalId() const; virtual void setEditLock (bool locked) = 0; + virtual void updateEditorSetting (const QString &, const QString &); signals: @@ -42,4 +43,4 @@ namespace CSVDoc }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 2857f4a54..f85a822d8 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -258,11 +258,14 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id) /// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis) SubView *view = mSubViewFactory.makeSubView (id, *mDocument); + view->setObjectName ("subview"); mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view); connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this, SLOT (addSubView (const CSMWorld::UniversalId&))); + CSMSettings::UserSettings::instance().updateSettings("Editor", "Record Status Display"); + view->show(); } @@ -366,20 +369,13 @@ void CSVDoc::View::showUserSettings() { CSVSettings::UserSettingsDialog *settingsDialog = new CSVSettings::UserSettingsDialog(this); - connect (&(CSMSettings::UserSettings::instance()), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)), - this, SLOT (slotUpdateEditorSetting (const QString &, const QString &)) ); - settingsDialog->show(); } -void CSVDoc::View::slotUpdateEditorSetting(const QString &settingName, const QString &settingValue) +void CSVDoc::View::updateEditorSetting (const QString &settingName, const QString &settingValue) { - static QString lastValue = ""; - - if (lastValue != settingValue) - { - //evaluate settingName against tokens to determine which function to call to update Editor application. - - lastValue = settingValue; - } + if (settingName == "Record Status Display") + foreach (QObject *view, mSubViewWindow.children()) + if (view->objectName() == "subview") + dynamic_cast(view)->updateEditorSetting (settingName, settingValue); } diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 0552a86cb..2fbe881eb 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -68,6 +68,8 @@ namespace CSVDoc void exitApplication(); + void loadUserSettings(); + public: View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); @@ -88,6 +90,8 @@ namespace CSVDoc Operations *getOperations() const; + void updateEditorSetting (const QString &, const QString &); + signals: void newDocumentRequest(); @@ -102,8 +106,6 @@ namespace CSVDoc void abortOperation (int type); - void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue); - private slots: void newView(); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 97dd8b997..a5ccc9efc 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -13,13 +13,13 @@ #include "../world/enumdelegate.hpp" #include "../world/vartypedelegate.hpp" #include "../world/recordstatusdelegate.hpp" +#include "../settings/usersettingsdialog.hpp" #include "view.hpp" #include #include #include -#include void CSVDoc::ViewManager::updateIndices() { @@ -121,6 +121,11 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_RecordState, new CSVWorld::RecordStatusDelegateFactory() ); + + connect (&CSMSettings::UserSettings::instance(), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)), + this, SLOT (slotUpdateEditorSetting (const QString &, const QString &))); + + CSMSettings::UserSettings::instance().loadSettings("opencs.cfg"); } CSVDoc::ViewManager::~ViewManager() @@ -347,3 +352,10 @@ void CSVDoc::ViewManager::exitApplication (CSVDoc::View *view) if (notifySaveOnClose (view)) QApplication::instance()->exit(); } + +void CSVDoc::ViewManager::slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) +{ + if (settingName == "Record Status Display") + foreach (CSVDoc::View *view, mViews) + view->updateEditorSetting (settingName, settingValue); +} diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 90f23eaa1..2b0890a21 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -72,6 +72,8 @@ namespace CSVDoc void progress (int current, int max, int type, int threads, CSMDoc::Document *document); void onExitWarningHandler(int state, CSMDoc::Document* document); + + void slotUpdateEditorSetting (const QString &, const QString &); }; } diff --git a/apps/opencs/view/settings/abstractpage.cpp b/apps/opencs/view/settings/abstractpage.cpp index 512b5abbd..6e34af63b 100644 --- a/apps/opencs/view/settings/abstractpage.cpp +++ b/apps/opencs/view/settings/abstractpage.cpp @@ -13,18 +13,32 @@ CSVSettings::AbstractPage::AbstractPage(QWidget *parent): QWidget(parent) { + QGridLayout *pageLayout = new QGridLayout(this); + setLayout (pageLayout); } CSVSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent): QWidget(parent) { QWidget::setObjectName (pageName); + + QGridLayout *pageLayout = new QGridLayout(this); + setLayout (pageLayout); } CSVSettings::AbstractPage::~AbstractPage() { } - +/* +void CSVSettings::AbstractPage::setupUi() +{ + // Hacks to get the stylesheet look properly + #ifdef Q_OS_MAC + QPlastiqueStyle *style = new QPlastiqueStyle; + //profilesComboBox->setStyle(style); + #endif +} +*/ CSMSettings::SettingList *CSVSettings::AbstractPage::getSettings() { CSMSettings::SettingList *settings = new CSMSettings::SettingList(); diff --git a/apps/opencs/view/settings/abstractpage.hpp b/apps/opencs/view/settings/abstractpage.hpp index 15ac82a62..1665b59d2 100644 --- a/apps/opencs/view/settings/abstractpage.hpp +++ b/apps/opencs/view/settings/abstractpage.hpp @@ -28,7 +28,7 @@ namespace CSVSettings { ~AbstractPage(); - virtual void setupUi()=0; + virtual void setupUi() = 0; virtual void initializeWidgets (const CSMSettings::SettingMap &settings) = 0; @@ -39,7 +39,7 @@ namespace CSVSettings { protected: template - AbstractBlock *buildBlock (T &def) + AbstractBlock *buildBlock (T *def) { S *block = new S (this); int ret = block->build (def); @@ -47,12 +47,12 @@ namespace CSVSettings { if (ret < 0) return 0; - QWidget::layout()->addWidget (block->getGroupBox()); + QGroupBox *box = block->getGroupBox(); + QWidget::layout()->addWidget (box); return block; } - }; } diff --git a/apps/opencs/view/settings/blankpage.cpp b/apps/opencs/view/settings/blankpage.cpp index 57d5c7caa..bf9c3c86e 100644 --- a/apps/opencs/view/settings/blankpage.cpp +++ b/apps/opencs/view/settings/blankpage.cpp @@ -43,10 +43,7 @@ void CSVSettings::BlankPage::initPage() void CSVSettings::BlankPage::setupUi() { QGroupBox *pageBox = new QGroupBox(this); - QLayout* pageLayout = new QVBoxLayout(); - - setLayout(pageLayout); - pageLayout->addWidget(pageBox); + layout()->addWidget(pageBox); } void CSVSettings::BlankPage::initializeWidgets (const CSMSettings::SettingMap &settings) diff --git a/apps/opencs/view/settings/customblock.cpp b/apps/opencs/view/settings/customblock.cpp index f44189569..933abf423 100644 --- a/apps/opencs/view/settings/customblock.cpp +++ b/apps/opencs/view/settings/customblock.cpp @@ -23,7 +23,7 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis for (; listIt != defList.end(); ++listIt) { if (!(*listIt)->isProxy) - retVal = buildGroupBlock (*(*listIt)); + retVal = buildGroupBlock (*listIt); else { mGroupList << proxyBlock; @@ -32,7 +32,7 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis } if (proxyIt != defaultIt) - retVal = buildProxyBlock (*(*proxyIt), proxyBlock); + retVal = buildProxyBlock (*proxyIt, proxyBlock); return retVal; } @@ -45,7 +45,7 @@ CSVSettings::GroupBox *CSVSettings::CustomBlock::buildGroupBox (Orientation orie return box; } -int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def) +int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef *def) { GroupBlock *block = new GroupBlock (getParent()); @@ -57,9 +57,9 @@ int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def) return block->build(def); } -int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *block) +int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef *def, ProxyBlock *block) { - if (def.properties.size() != 1) + if (def->properties.size() != 1) return -1; int retVal = block->build(def); @@ -67,7 +67,7 @@ int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *bl if (retVal != 0) return retVal; - foreach (QStringList *list, *(def.properties.at(0)->proxyList)) + foreach (QStringList *list, *(def->properties.at(0)->proxyList)) { QString proxiedBlockName = list->at(0); diff --git a/apps/opencs/view/settings/customblock.hpp b/apps/opencs/view/settings/customblock.hpp index b2f2a0261..f831a90ba 100644 --- a/apps/opencs/view/settings/customblock.hpp +++ b/apps/opencs/view/settings/customblock.hpp @@ -29,8 +29,8 @@ namespace CSVSettings private: - int buildGroupBlock(GroupBlockDef &def); - int buildProxyBlock(GroupBlockDef &def, ProxyBlock *block); + int buildGroupBlock(GroupBlockDef *def); + int buildProxyBlock(GroupBlockDef *def, ProxyBlock *block); }; } #endif // CUSTOMBLOCK_HPP diff --git a/apps/opencs/view/settings/editorpage.cpp b/apps/opencs/view/settings/editorpage.cpp index ad5a15f6f..7d67312e7 100644 --- a/apps/opencs/view/settings/editorpage.cpp +++ b/apps/opencs/view/settings/editorpage.cpp @@ -1,156 +1,52 @@ #include "editorpage.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef Q_OS_MAC -#include -#endif - -#include "../../model/settings/usersettings.hpp" #include "groupblock.hpp" -#include "toggleblock.hpp" +#include "../../model/settings/usersettings.hpp" -CSVSettings::EditorPage::EditorPage(QWidget *parent): - AbstractPage("Editor", parent) +CSVSettings::EditorPage::EditorPage(QWidget* parent) : + AbstractPage(parent) { - // Hacks to get the stylesheet look properly -#ifdef Q_OS_MAC - QPlastiqueStyle *style = new QPlastiqueStyle; - //profilesComboBox->setStyle(style); -#endif - setupUi(); } -void CSVSettings::EditorPage::setupUi() +CSVSettings::EditorPage::EditorPage (const QString &pageName, QWidget* parent) + : AbstractPage (pageName, parent) { - GroupBlockDef undoStack (QString("Undo Stack Size")); - GroupBlockDef topLevelWindowCount (QString("Maximum Top-Level Window Count")); - GroupBlockDef reuseSubwindow (QString("Reuse Subwindows")); - GroupBlockDef customWindowSize (QString ("Custom Window Size")); - GroupBlockDef definedWindowSize (QString ("Pre-Defined Window Size")); - GroupBlockDef windowSizeToggle (QString ("Window Size")); - CustomBlockDef windowSize (QString ("Window Size")); - - //////////////////////////// - //undo stack size property - /////////////////////////// - - SettingsItemDef *undoStackItem = new SettingsItemDef (undoStack.title, "32"); - undoStack.properties << undoStackItem; - undoStackItem->minMax.left = "0"; - undoStackItem->minMax.right = "64"; - - WidgetDef stackWidget (Widget_SpinBox); - stackWidget.minMax = &(undoStackItem->minMax); - stackWidget.widgetWidth = 50; - - undoStackItem->widget = stackWidget; - - ////////////////////////////////////// - //number of top level windows property - ///////////////////////////////////// - - SettingsItemDef *topLevelItem = new SettingsItemDef (topLevelWindowCount.title, "100"); - topLevelWindowCount.properties << topLevelItem; - topLevelItem->minMax.left = "1"; - topLevelItem->minMax.right = "256"; - - WidgetDef topLvlWinWidget (Widget_SpinBox); - topLvlWinWidget.minMax = &(topLevelItem->minMax); - topLvlWinWidget.widgetWidth = 50; - - topLevelItem->widget = topLvlWinWidget; - - /////////////////////////// - //reuse subwindows property - //////////////////////////// - - SettingsItemDef *reuseSubItem = new SettingsItemDef (reuseSubwindow.title, "Reuse Subwindows"); - *(reuseSubItem->valueList) << "None" << "Top-Level" << "Document-Level"; - - WidgetDef reuseSubWidget (Widget_RadioButton); - reuseSubWidget.valueList = (reuseSubItem->valueList); - reuseSubWidget.widgetAlignment = Align_Left; - - reuseSubwindow.properties << reuseSubItem; - reuseSubItem->widget = reuseSubWidget; - - /////////////////////////////// - //custom window size properties - /////////////////////////////// - - //custom width - SettingsItemDef *widthItem = new SettingsItemDef ("Window Width", "640"); - widthItem->widget = WidgetDef (Widget_LineEdit); - widthItem->widget.widgetWidth = 45; - - //custom height - SettingsItemDef *heightItem = new SettingsItemDef ("Window Height", "480"); - heightItem->widget = WidgetDef (Widget_LineEdit); - heightItem->widget.widgetWidth = 45; - heightItem->widget.caption = "x"; - - customWindowSize.properties << widthItem << heightItem; - customWindowSize.widgetOrientation = Orient_Horizontal; - customWindowSize.isVisible = false; - - - //pre-defined - SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480"); - WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox); - widthByHeightWidget.widgetWidth = 90; - *(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768"; - - QStringList *widthProxy = new QStringList; - QStringList *heightProxy = new QStringList; - - (*widthProxy) << "Window Width" << "640" << "800" << "1024"; - (*heightProxy) << "Window Height" << "480" << "600" << "768"; - - *(widthByHeightItem->proxyList) << widthProxy << heightProxy; - - widthByHeightItem->widget = widthByHeightWidget; + setupUi(); +} - definedWindowSize.properties << widthByHeightItem; - definedWindowSize.isProxy = true; - definedWindowSize.isVisible = false; +CSVSettings::GroupBlockDef *CSVSettings::EditorPage::setupRecordStatusDisplay() +{ + GroupBlockDef *statusBlock = new GroupBlockDef(QString("Record Status Display")); - // window size toggle - windowSizeToggle.captions << "Pre-Defined" << "Custom"; - windowSizeToggle.widgetOrientation = Orient_Vertical; - windowSizeToggle.isVisible = false; + SettingsItemDef *statusItem = new SettingsItemDef (statusBlock->title, "Icon and Text"); + *(statusItem->valueList) << QString("Icon and Text") << QString("Icon Only") << QString("Text Only"); - //define a widget for each group in the toggle - for (int i = 0; i < 2; i++) - windowSizeToggle.widgets << new WidgetDef (Widget_RadioButton); + WidgetDef statusWidget (Widget_RadioButton); + statusWidget.valueList = statusItem->valueList; - windowSizeToggle.widgets.at(0)->isDefault = false; + statusItem->widget = statusWidget; - windowSize.blockDefList << &windowSizeToggle << &definedWindowSize << &customWindowSize; - windowSize.defaultValue = "Custom"; + statusBlock->properties << statusItem; - QGridLayout *pageLayout = new QGridLayout(this); + return statusBlock; +} - setLayout (pageLayout); +void CSVSettings::EditorPage::setupUi() +{ - mAbstractBlocks << buildBlock (topLevelWindowCount) - << buildBlock (reuseSubwindow) - << buildBlock (windowSize) - << buildBlock (undoStack); + mAbstractBlocks << buildBlock(setupRecordStatusDisplay()); foreach (AbstractBlock *block, mAbstractBlocks) { connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)), this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) ); } + + connect ( this, + SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)), + &(CSMSettings::UserSettings::instance()), + SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &))); + } void CSVSettings::EditorPage::initializeWidgets (const CSMSettings::SettingMap &settings) diff --git a/apps/opencs/view/settings/editorpage.hpp b/apps/opencs/view/settings/editorpage.hpp index 0c1e80e89..09769bf49 100644 --- a/apps/opencs/view/settings/editorpage.hpp +++ b/apps/opencs/view/settings/editorpage.hpp @@ -1,28 +1,30 @@ -#ifndef EDITORPAGE_H -#define EDITORPAGE_H +#ifndef EDITORPAGE_HPP +#define EDITORPAGE_HPP +#include "support.hpp" #include "abstractpage.hpp" -class QGroupBox; - -namespace CSVSettings { - - class UserSettings; - class AbstractBlock; - +namespace CSVSettings +{ class EditorPage : public AbstractPage { Q_OBJECT public: + explicit EditorPage(QWidget *parent = 0); + explicit EditorPage (const QString &pageName, QWidget* parent = 0); - EditorPage(QWidget *parent = 0); - - void setupUi(); void initializeWidgets (const CSMSettings::SettingMap &settings); + void setupUi(); + + private: + GroupBlockDef *setupRecordStatusDisplay(); signals: void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue); + + public slots: }; } -#endif //EDITORPAGE_H + +#endif // EDITORPAGE_HPP diff --git a/apps/opencs/view/settings/groupblock.cpp b/apps/opencs/view/settings/groupblock.cpp index b18f629ba..f23a4ae28 100644 --- a/apps/opencs/view/settings/groupblock.cpp +++ b/apps/opencs/view/settings/groupblock.cpp @@ -9,22 +9,22 @@ CSVSettings::GroupBlock::GroupBlock (bool isVisible, QWidget *parent) : AbstractBlock (isVisible, parent) {} -int CSVSettings::GroupBlock::build (GroupBlockDef &def) +int CSVSettings::GroupBlock::build (GroupBlockDef *def) { - if (def.properties.size() == 0) + if (def->properties.size() == 0) return -1; int retVal = 0; - setVisible (def.isVisible); + setVisible (def->isVisible); - mBox->setLayout(createLayout (def.widgetOrientation, true)); + mBox->setLayout(createLayout (def->widgetOrientation, true)); - setObjectName (def.title); - mBox->setTitle (def.title); + setObjectName (def->title); + mBox->setTitle (def->title); - foreach (SettingsItemDef *itemDef, def.properties) + foreach (SettingsItemDef *itemDef, def->properties) { ItemBlock *block = new ItemBlock (mBox); diff --git a/apps/opencs/view/settings/groupblock.hpp b/apps/opencs/view/settings/groupblock.hpp index a8fd4e3b4..bd16d0b5b 100644 --- a/apps/opencs/view/settings/groupblock.hpp +++ b/apps/opencs/view/settings/groupblock.hpp @@ -16,7 +16,7 @@ namespace CSVSettings GroupBlock (QWidget* parent = 0); GroupBlock (bool isVisible, QWidget *parent = 0); - int build (GroupBlockDef &def); + int build (GroupBlockDef *def); bool updateSettings (const CSMSettings::SettingMap &settings); diff --git a/apps/opencs/view/settings/proxyblock.cpp b/apps/opencs/view/settings/proxyblock.cpp index 71a307084..f47c9dd07 100644 --- a/apps/opencs/view/settings/proxyblock.cpp +++ b/apps/opencs/view/settings/proxyblock.cpp @@ -5,10 +5,10 @@ CSVSettings::ProxyBlock::ProxyBlock (QWidget *parent) : GroupBlock (parent) { } -int CSVSettings::ProxyBlock::build (GroupBlockDef &proxyDef) +int CSVSettings::ProxyBlock::build (GroupBlockDef *proxyDef) { //get the list of pre-defined values for the proxy - mValueList = proxyDef.properties.at(0)->valueList; + mValueList = proxyDef->properties.at(0)->valueList; bool success = GroupBlock::build(proxyDef); diff --git a/apps/opencs/view/settings/proxyblock.hpp b/apps/opencs/view/settings/proxyblock.hpp index f757842ea..73d31fecf 100644 --- a/apps/opencs/view/settings/proxyblock.hpp +++ b/apps/opencs/view/settings/proxyblock.hpp @@ -21,7 +21,7 @@ namespace CSVSettings explicit ProxyBlock (ItemBlock *proxyItemBlock, QWidget *parent = 0); void addSetting (ItemBlock* settingBlock, QStringList *proxyList); - int build (GroupBlockDef &def); + int build (GroupBlockDef *def); CSMSettings::SettingList *getSettings() { return 0; } bool updateSettings (const CSMSettings::SettingMap &settings); diff --git a/apps/opencs/view/settings/samplepage.cpp b/apps/opencs/view/settings/samplepage.cpp new file mode 100644 index 000000000..1ed2f0505 --- /dev/null +++ b/apps/opencs/view/settings/samplepage.cpp @@ -0,0 +1,159 @@ +#include "samplepage.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_MAC +#include +#endif + +#include "../../model/settings/usersettings.hpp" +#include "groupblock.hpp" +#include "toggleblock.hpp" + +CSVSettings::SamplePage::SamplePage(QWidget *parent): + AbstractPage("Editor", parent) +{ + // Hacks to get the stylesheet look properly +#ifdef Q_OS_MAC + QPlastiqueStyle *style = new QPlastiqueStyle; + //profilesComboBox->setStyle(style); +#endif + + setupUi(); +} + +void CSVSettings::SamplePage::setupUi() +{ + GroupBlockDef *undoStack = new GroupBlockDef(QString("Undo Stack Size")); + GroupBlockDef *topLevelWindowCount = new GroupBlockDef(QString("Maximum Top-Level Window Count")); + GroupBlockDef *reuseSubwindow = new GroupBlockDef(QString("Reuse Subwindows")); + GroupBlockDef *customWindowSize = new GroupBlockDef(QString ("Custom Window Size")); + GroupBlockDef *definedWindowSize = new GroupBlockDef(QString ("Pre-Defined Window Size")); + GroupBlockDef *windowSizeToggle = new GroupBlockDef(QString ("Window Size")); + CustomBlockDef *windowSize = new CustomBlockDef(QString ("Window Size")); + + //////////////////////////// + //undo stack size property + /////////////////////////// + + SettingsItemDef *undoStackItem = new SettingsItemDef (undoStack->title, "32"); + undoStack->properties << undoStackItem; + undoStackItem->minMax.left = "0"; + undoStackItem->minMax.right = "64"; + + WidgetDef stackWidget (Widget_SpinBox); + stackWidget.minMax = &(undoStackItem->minMax); + stackWidget.widgetWidth = 50; + + undoStackItem->widget = stackWidget; + + ////////////////////////////////////// + //number of top level windows property + ///////////////////////////////////// + + SettingsItemDef *topLevelItem = new SettingsItemDef (topLevelWindowCount->title, "100"); + topLevelWindowCount->properties << topLevelItem; + topLevelItem->minMax.left = "1"; + topLevelItem->minMax.right = "256"; + + WidgetDef topLvlWinWidget (Widget_SpinBox); + topLvlWinWidget.minMax = &(topLevelItem->minMax); + topLvlWinWidget.widgetWidth = 50; + + topLevelItem->widget = topLvlWinWidget; + + /////////////////////////// + //reuse subwindows property + //////////////////////////// + + SettingsItemDef *reuseSubItem = new SettingsItemDef (reuseSubwindow->title, "Reuse Subwindows"); + *(reuseSubItem->valueList) << "None" << "Top-Level" << "Document-Level"; + + WidgetDef reuseSubWidget (Widget_RadioButton); + reuseSubWidget.valueList = (reuseSubItem->valueList); + reuseSubWidget.widgetAlignment = Align_Left; + + reuseSubwindow->properties << reuseSubItem; + reuseSubItem->widget = reuseSubWidget; + + /////////////////////////////// + //custom window size properties + /////////////////////////////// + + //custom width + SettingsItemDef *widthItem = new SettingsItemDef ("Window Width", "640"); + widthItem->widget = WidgetDef (Widget_LineEdit); + widthItem->widget.widgetWidth = 45; + + //custom height + SettingsItemDef *heightItem = new SettingsItemDef ("Window Height", "480"); + heightItem->widget = WidgetDef (Widget_LineEdit); + heightItem->widget.widgetWidth = 45; + heightItem->widget.caption = "x"; + + customWindowSize->properties << widthItem << heightItem; + customWindowSize->widgetOrientation = Orient_Horizontal; + customWindowSize->isVisible = false; + + + //pre-defined + SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480"); + WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox); + widthByHeightWidget.widgetWidth = 90; + *(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768"; + + QStringList *widthProxy = new QStringList; + QStringList *heightProxy = new QStringList; + + (*widthProxy) << "Window Width" << "640" << "800" << "1024"; + (*heightProxy) << "Window Height" << "480" << "600" << "768"; + + *(widthByHeightItem->proxyList) << widthProxy << heightProxy; + + widthByHeightItem->widget = widthByHeightWidget; + + definedWindowSize->properties << widthByHeightItem; + definedWindowSize->isProxy = true; + definedWindowSize->isVisible = false; + + // window size toggle + windowSizeToggle->captions << "Pre-Defined" << "Custom"; + windowSizeToggle->widgetOrientation = Orient_Vertical; + windowSizeToggle->isVisible = false; + + //define a widget for each group in the toggle + for (int i = 0; i < 2; i++) + windowSizeToggle->widgets << new WidgetDef (Widget_RadioButton); + + windowSizeToggle->widgets.at(0)->isDefault = false; + + windowSize->blockDefList << windowSizeToggle << definedWindowSize << customWindowSize; + windowSize->defaultValue = "Custom"; + + mAbstractBlocks << buildBlock (topLevelWindowCount) + << buildBlock (reuseSubwindow) + << buildBlock (windowSize) + << buildBlock (undoStack); + + foreach (AbstractBlock *block, mAbstractBlocks) + { + connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)), + this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) ); + } +} + +void CSVSettings::SamplePage::initializeWidgets (const CSMSettings::SettingMap &settings) +{ + //iterate each item in each blocks in this section + //validate the corresponding setting against the defined valuelist if any. + for (AbstractBlockList::Iterator it_block = mAbstractBlocks.begin(); + it_block != mAbstractBlocks.end(); ++it_block) + (*it_block)->updateSettings (settings); +} diff --git a/apps/opencs/view/settings/samplepage.hpp b/apps/opencs/view/settings/samplepage.hpp new file mode 100644 index 000000000..3a9448bad --- /dev/null +++ b/apps/opencs/view/settings/samplepage.hpp @@ -0,0 +1,28 @@ +#ifndef SAMPLEPAGE_H +#define SAMPLEPAGE_H + +#include "abstractpage.hpp" + +class QGroupBox; + +namespace CSVSettings { + + class UserSettings; + class AbstractBlock; + + class SamplePage : public AbstractPage + { + Q_OBJECT + + public: + + explicit SamplePage(QWidget *parent = 0); + + void setupUi(); + void initializeWidgets (const CSMSettings::SettingMap &settings); + + signals: + void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue); + }; +} +#endif //SAMPLEPAGE_H diff --git a/apps/opencs/view/settings/toggleblock.cpp b/apps/opencs/view/settings/toggleblock.cpp index 12a42ca9c..3406a62c4 100644 --- a/apps/opencs/view/settings/toggleblock.cpp +++ b/apps/opencs/view/settings/toggleblock.cpp @@ -7,24 +7,24 @@ CSVSettings::ToggleBlock::ToggleBlock(QWidget *parent) : CustomBlock(parent) {} -int CSVSettings::ToggleBlock::build(CustomBlockDef &def) +int CSVSettings::ToggleBlock::build(CustomBlockDef *def) { - if (def.blockDefList.size()==0) + if (def->blockDefList.size()==0) return -1; - QList::Iterator it = def.blockDefList.begin(); + QList::Iterator it = def->blockDefList.begin(); //first def in the list is the def for the toggle block GroupBlockDef *toggleDef = *it++; - if (toggleDef->captions.size() != def.blockDefList.size()-1 ) + if (toggleDef->captions.size() != def->blockDefList.size()-1 ) return -2; if (toggleDef->widgets.size() == 0) return -3; //create the toogle block UI structure - QLayout *blockLayout = createLayout (def.blockOrientation, true); + QLayout *blockLayout = createLayout (def->blockOrientation, true); GroupBox *propertyBox = buildGroupBox (toggleDef->widgetOrientation); mBox->setLayout(blockLayout); @@ -34,13 +34,13 @@ int CSVSettings::ToggleBlock::build(CustomBlockDef &def) //this manages proxy block construction. //Any settings managed by the proxy setting //must be included in the blocks defined in the list. - CustomBlock::build (def.blockDefList, &it); + CustomBlock::build (def->blockDefList, &it); for (GroupBlockList::iterator it = mGroupList.begin(); it != mGroupList.end(); ++it) propertyBox->layout()->addWidget ((*it)->getGroupBox()); //build togle widgets, linking them to the settings - GroupBox *toggleBox = buildToggleWidgets (*toggleDef, def.defaultValue); + GroupBox *toggleBox = buildToggleWidgets (toggleDef, def->defaultValue); blockLayout->addWidget(toggleBox); blockLayout->addWidget(propertyBox); @@ -49,16 +49,16 @@ int CSVSettings::ToggleBlock::build(CustomBlockDef &def) return 0; } -CSVSettings::GroupBox *CSVSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle) +CSVSettings::GroupBox *CSVSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef *def, QString &defaultToggle) { GroupBox *box = new GroupBox (false, getParent()); - QLayout *layout = createLayout (def.widgetOrientation, true, static_cast(box)); + QLayout *layout = createLayout (def->widgetOrientation, true, static_cast(box)); - for (int i = 0; i < def.widgets.size(); ++i) + for (int i = 0; i < def->widgets.size(); ++i) { - QString caption = def.captions.at(i); - WidgetDef *wDef = def.widgets.at(i); + QString caption = def->captions.at(i); + WidgetDef *wDef = def->widgets.at(i); wDef->caption = caption; wDef->widgetAlignment = Align_Left; diff --git a/apps/opencs/view/settings/toggleblock.hpp b/apps/opencs/view/settings/toggleblock.hpp index 8afe701b8..db617e767 100644 --- a/apps/opencs/view/settings/toggleblock.hpp +++ b/apps/opencs/view/settings/toggleblock.hpp @@ -18,10 +18,10 @@ namespace CSVSettings public: explicit ToggleBlock(QWidget *parent = 0); - int build (CustomBlockDef &def); + int build (CustomBlockDef *def); private: - GroupBox *buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle); + GroupBox *buildToggleWidgets (GroupBlockDef *def, QString &defaultToggle); }; } #endif // TOGGLEBLOCK_HPP diff --git a/apps/opencs/view/settings/usersettingsdialog.cpp b/apps/opencs/view/settings/usersettingsdialog.cpp index 012fc0408..c48e0ee97 100644 --- a/apps/opencs/view/settings/usersettingsdialog.cpp +++ b/apps/opencs/view/settings/usersettingsdialog.cpp @@ -9,26 +9,27 @@ #include #include #include +#include #include "blankpage.hpp" -#include "editorpage.hpp" -#include "../../model/settings/support.hpp" +#include "samplepage.hpp" +#include "../../model/settings/support.hpp" +#include #include "settingwidget.hpp" -#include CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) : QMainWindow (parent), mStackedWidget (0) { setWindowTitle(QString::fromUtf8 ("User Settings")); buildPages(); - setWidgetStates (loadSettings()); + setWidgetStates (); positionWindow (); connect (mListWidget, SIGNAL (currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, - SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*))); + SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*))); } CSVSettings::UserSettingsDialog::~UserSettingsDialog() @@ -40,13 +41,16 @@ void CSVSettings::UserSettingsDialog::closeEvent (QCloseEvent *event) writeSettings(); } -void CSVSettings::UserSettingsDialog::setWidgetStates (CSMSettings::SectionMap settingsMap) +void CSVSettings::UserSettingsDialog::setWidgetStates () { + CSMSettings::UserSettings::instance().loadSettings("opencs.cfg"); + const CSMSettings::SectionMap §ionSettings = CSMSettings::UserSettings::instance().getSettings(); + //iterate the tabWidget's pages (sections) for (int i = 0; i < mStackedWidget->count(); i++) { //get the settings defined for the entire section - CSMSettings::SettingMap *settings = settingsMap [mStackedWidget->widget(i)->objectName()]; + CSMSettings::SettingMap *settings = sectionSettings [mStackedWidget->widget(i)->objectName()]; //if found, initialize the page's widgets if (settings) @@ -65,18 +69,25 @@ void CSVSettings::UserSettingsDialog::buildPages() mListWidget = new QListWidget (centralWidget); mStackedWidget = new QStackedWidget (centralWidget); - QLayout* dialogLayout = new QHBoxLayout(); + QGridLayout* dialogLayout = new QGridLayout(); - dialogLayout->addWidget (mListWidget); - dialogLayout->addWidget (mStackedWidget); + mListWidget->setMinimumWidth(0); + mListWidget->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Expanding); + + mStackedWidget->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); + + dialogLayout->addWidget (mListWidget,0,0); + dialogLayout->addWidget (mStackedWidget,0,1, Qt::AlignTop); centralWidget->setLayout (dialogLayout); setCentralWidget (centralWidget); setDockOptions (QMainWindow::AllowNestedDocks); + //uncomment to test with sample editor page. - //createSamplePage(); - createPage("Page1"); + // TODO: Reimplement sample page using createPage function + //createPage("Sample"); + createPage("Editor"); createPage("Page2"); createPage("Page3"); } @@ -85,14 +96,16 @@ void CSVSettings::UserSettingsDialog::createSamplePage() { //add pages to stackedwidget and items to listwidget CSVSettings::AbstractPage *page - = new CSVSettings::EditorPage(this); + = new CSVSettings::SamplePage(this); mStackedWidget->addWidget (page); - new QListWidgetItem (page->objectName(), mListWidget); + connect ( page, + SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)), + &(CSMSettings::UserSettings::instance()), + SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &))); - connect ( page, SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)), - &(CSMSettings::UserSettings::instance()), SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &))); + new QListWidgetItem (page->objectName(), mListWidget); } void CSVSettings::UserSettingsDialog::positionWindow () @@ -103,47 +116,6 @@ void CSVSettings::UserSettingsDialog::positionWindow () } -CSMSettings::SectionMap CSVSettings::UserSettingsDialog::loadSettings () -{ - QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); - - mPaths.append(QString("opencs.cfg")); - mPaths.append(userPath + QString("opencs.cfg")); - - CSMSettings::SectionMap settingsMap; - - foreach (const QString &path, mPaths) - { - qDebug() << "Loading config file:" << qPrintable(path); - QFile file(path); - - if (file.exists()) - { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error opening OpenCS configuration file")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(QObject::tr("
Could not open %0 for reading

\ - Please make sure you have the right permissions \ - and try again.
").arg(file.fileName())); - msgBox.exec(); - return settingsMap; - } - - QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-8")); - - CSMSettings::UserSettings::instance().getSettings(stream, settingsMap); - } - - file.close(); - } - - return settingsMap; -} - void CSVSettings::UserSettingsDialog::writeSettings() { QMap settings; @@ -154,7 +126,7 @@ void CSVSettings::UserSettingsDialog::writeSettings() settings [page->objectName()] = page->getSettings(); } - CSMSettings::UserSettings::instance().writeFile(CSMSettings::UserSettings::instance().openFile(mPaths.back()), settings); + CSMSettings::UserSettings::instance().writeFile(settings); } diff --git a/apps/opencs/view/settings/usersettingsdialog.hpp b/apps/opencs/view/settings/usersettingsdialog.hpp index 31d40ca01..5e73fd123 100644 --- a/apps/opencs/view/settings/usersettingsdialog.hpp +++ b/apps/opencs/view/settings/usersettingsdialog.hpp @@ -4,14 +4,13 @@ #include #include #include - -#ifndef Q_MOC_RUN -#include -#endif +#include #include "../../model/settings/usersettings.hpp" #include "../../model/settings/support.hpp" +#include "editorpage.hpp" + class QHBoxLayout; class AbstractWidget; class QStackedWidget; @@ -28,7 +27,6 @@ namespace CSVSettings { QStringList mPaths; QListWidget *mListWidget; QStackedWidget *mStackedWidget; - Files::ConfigurationManager mCfgMgr; public: UserSettingsDialog(QMainWindow *parent = 0); @@ -38,10 +36,9 @@ namespace CSVSettings { void closeEvent (QCloseEvent *event); AbstractPage *getAbstractPage (int index); - void setWidgetStates (CSMSettings::SectionMap settingsMap); + void setWidgetStates (); void buildPages(); void positionWindow (); - CSMSettings::SectionMap loadSettings(); void writeSettings(); void createSamplePage(); @@ -61,6 +58,12 @@ namespace CSVSettings { if (mStackedWidget->sizeHint().height() < 480) mStackedWidget->sizeHint().setHeight(480); + QFontMetrics fm (QApplication::font()); + int textWidth = fm.width(page->objectName()); + + if ((textWidth + 50) > mListWidget->minimumWidth()) + mListWidget->setMinimumWidth(textWidth + 50); + resize (mStackedWidget->sizeHint()); } diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp index aa9487b70..3c61c4af4 100644 --- a/apps/opencs/view/world/recordstatusdelegate.cpp +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "../../model/settings/usersettings.hpp" CSVWorld::RecordStatusDelegate::RecordStatusDelegate(QUndoStack &undoStack, QObject *parent) : CommandDelegate (undoStack, parent) @@ -36,23 +37,23 @@ void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptio switch (index.data().toInt()) { case 0: // State_BaseOnly - text = "base"; + text = "Base"; break; case 1: // State_Modified - text = "modified"; + text = "Modified"; icon = mModifiedIcon; break; case 2: // State_Modified_Only - text = "added"; + text = "Added"; icon = mAddedIcon; break; case 3: // State_Deleted case 4: // State_Erased - text = "deleted"; + text = "Deleted"; icon = mDeletedIcon; break; @@ -70,14 +71,14 @@ void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptio if (mStatusDisplay == 0 && (icon) ) { - iconRect.setRight (iconRect.left() + mIconSize*2); - textRect.setLeft (iconRect.right() + mTextLeftOffset *2); + iconRect.setRight (iconRect.left()+ mIconSize*2); + textRect.setLeft (iconRect.right() + mTextLeftOffset *1.25); } else textRect.setLeft (textRect.left() + mTextLeftOffset ); if ( (mStatusDisplay == 0 || mStatusDisplay == 1) && (icon) ) - painter->drawPixmap(iconRect.center(),icon->pixmap(mIconSize, mIconSize)); + painter->drawPixmap(iconRect.center().x()-10,iconRect.center().y()+2, icon->pixmap(mIconSize, mIconSize)); // icon + text or text only, or force text if no icon exists for status if (mStatusDisplay == 0 || mStatusDisplay == 2 || !(icon) ) @@ -99,3 +100,21 @@ CSVWorld::CommandDelegate *CSVWorld::RecordStatusDelegateFactory::makeDelegate ( { return new RecordStatusDelegate (undoStack, parent); } + +void CSVWorld::RecordStatusDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue) +{ + if (settingName == "Record Status Display") + { + if (settingValue == "Icon and Text") + mStatusDisplay = 0; + + else if (settingValue == "Icon Only") + mStatusDisplay = 1; + + else if (settingValue == "Text Only") + mStatusDisplay = 2; + + else + mStatusDisplay = 0; + } +} diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp index 9ab19d30e..3f53f2f55 100644 --- a/apps/opencs/view/world/recordstatusdelegate.hpp +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -35,12 +35,12 @@ namespace CSVWorld QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const; + void updateEditorSetting (const QString &settingName, const QString &settingValue); + }; class RecordStatusDelegateFactory : public CommandDelegateFactory { - //std::vector > mValues; - public: virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const; diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index f9167d259..1ec0dde09 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -12,6 +12,7 @@ #include "../../model/world/idtableproxymodel.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/record.hpp" +#include "recordstatusdelegate.hpp" #include "util.hpp" @@ -80,7 +81,7 @@ std::vector CSVWorld::Table::listDeletableSelectedIds() const CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete) -: mUndoStack (undoStack), mCreateAction (0), mEditLock (false) + : mUndoStack (undoStack), mCreateAction (0), mEditLock (false), mRecordStatusDisplay (0) { mModel = &dynamic_cast (*data.getTableModel (id)); @@ -161,6 +162,7 @@ void CSVWorld::Table::createRecord() mUndoStack.push (new CSMWorld::CreateCommand (*mProxyModel, stream.str())); } + } void CSVWorld::Table::revertRecord() @@ -201,4 +203,13 @@ void CSVWorld::Table::deleteRecord() mUndoStack.endMacro(); } } -} \ No newline at end of file +} + +void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue) +{ + if (settingName == "Record Status Display") + { + dynamic_cast(this->itemDelegateForColumn(1))->updateEditorSetting (settingName, settingValue); + emit dataChanged(mModel->index(0,1), mModel->index(mModel->rowCount()-1, 1)); + } +} diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index df0224583..348e800cf 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -34,6 +34,7 @@ namespace CSVWorld CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTable *mModel; bool mEditLock; + int mRecordStatusDisplay; private: @@ -52,6 +53,8 @@ namespace CSVWorld CSMWorld::UniversalId getUniversalId (int row) const; + void updateEditorSetting (const QString &settingName, const QString &settingValue); + private slots: void createRecord(); diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index bb4bb76c6..d139ef74b 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -22,4 +22,11 @@ void CSVWorld::TableSubView::setEditLock (bool locked) void CSVWorld::TableSubView::rowActivated (const QModelIndex& index) { focusId (mTable->getUniversalId (index.row())); -} \ No newline at end of file +} + +void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, const QString &settingValue) +{ + + if (settingName == "Record Status Display") + mTable->updateEditorSetting(settingName, settingValue); +} diff --git a/apps/opencs/view/world/tablesubview.hpp b/apps/opencs/view/world/tablesubview.hpp index 0e7b8aa30..13db8255a 100644 --- a/apps/opencs/view/world/tablesubview.hpp +++ b/apps/opencs/view/world/tablesubview.hpp @@ -23,8 +23,8 @@ namespace CSVWorld public: TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete); - virtual void setEditLock (bool locked); + void updateEditorSetting (const QString &, const QString &); private slots: @@ -32,4 +32,4 @@ namespace CSVWorld }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 95dfec6c5..251564e96 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -82,6 +82,8 @@ namespace CSVWorld ///< \brief Use commands instead of manipulating the model directly class CommandDelegate : public QStyledItemDelegate { + Q_OBJECT + QUndoStack& mUndoStack; bool mEditLock; @@ -105,6 +107,10 @@ namespace CSVWorld void setEditLock (bool locked); bool isEditLocked() const; + + private slots: + + virtual void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) {} }; } From a5d9d3fd7aac1614e987fe505d12eae394a69b1d Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 15 Jun 2013 07:29:20 -0500 Subject: [PATCH 129/213] Updated status icons from sirherrbatka --- files/opencs/added.png | Bin 1223 -> 840 bytes files/opencs/modified.png | Bin 1855 -> 2022 bytes files/opencs/removed.png | Bin 1490 -> 1311 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/files/opencs/added.png b/files/opencs/added.png index 456966a9c953555eb33677f2c6ad507b01b58529..091e3c61a60c0c0d403f2ae1f900c88ed0cf1521 100644 GIT binary patch delta 816 zcmV-01JC@&3CIRUiBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hX4Qo1am@3 zR0s$N2z&@+hyVZp32;bRa{vGh*8l(w*8xH(n|PC!1Sfw2#Ysd#RA_$K;OffNJ9fl0B4CVD zj6-1}RY`wbN`4VnQR8y@p2H~~;}Aofl!)l$1|%vh;X2;M`?!|b$0K}=Z}1b2#Zk%P zJOW-t51*l1*w0&dfS<+D$fi^Pao(?@Ti3O%t*xx!&CN{*2M5>iCcZDuB7~6L#QEOE zCkSh6Yay5Q_4Oc5ncL#@TP(?Cp;-A#LMxzYS^4Pl!n@O9+#K8R*Kfu%! z#uR1}5GKBpXE~OYnUowlRBA^!xpZ0lb%T zUcT_R(N;jyv;vx@70@)TfTn2$G)*OXp>=HGR;iiW+1bg8+1S{yyStkelgu1(J@q#3 zcSH~VC+_0LU@+*Wi~d*k_xJ7X?G=UMD=~lPaR(| z<|}Ca!mpx;0Zt|(@Q1j>{ZL*>$@vBRD2h0gQBsQ4*|-xz2so*#>R4Rjp0}u{a7p|h zJQnu~9;M`F@qAG~JsVHVwZV{959TSt=V7|l6hfFsz;j&q+h{AGX<7kI(+X&s^K4+V z2JvZVI2_vE-p&d>Iy#yhjudQgKg*(go3+M!_$4J!(hl(fURSuyS~>y&PefC7M_gB} uGy6Eem*Ot{6NRI2;a~PB62Qyzy3OAq4O5KW_#Zd`0000!lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D(<+r!7#%P+tuAjnTgR~zU^H8nLI9W7sfA6q+Xdq+DLS0^_Q7f&yD{{SB! zUr%KfB~ek)r%#_sNl7UxD|q{Q+Sppz+1q+~yDKRvNk~Zi|Nmc3PEJu#-rB|z=n;2M zS1%tAMJ1s1a+X%+);3o54t8?#axQL8<`!lSj`mJ2jzBNFx;s0$ILOJ%%F4<(Iy;z} znOIp{+SpnH!$DR~Mp{PN$k@=>#K^?d$jsct+``n#+QP!pOiD^pLQ-5`Ur$q0Lql8c)Q2qYxLWn`qZwY9{=#q{*_OiWC~CB)S=)cN`O)YMe@`1q8SmH7C0 z6%^!oczA#ob8~Y`OG|Nba*B$IaBy%434tPjg@r{xKtM=Hh@G9Cjg74;gmninj5tby z{DO7w|GoeB?|t0`H|1vn#Tb*k-CcBc-7Q=VvL>2>6&TkNA4N5OK$N4p$&#d4yc`JapLjb($+eiOJ6f?2P<3F(sRG(O#U?g z+mFI`KbGx%_x+vC^WA$Z?B+9HxR9|;Aos0oSoZR>_paW(o4UO;YJSO$I0Wq@uT64 zCzDl<`f^@AQ_W*%aQTpk`$W$=p(7&p%`P_%?KJ%H`&Yvb$-H|Q=cZyh-=xJQ&yWCe8=nQCkc_FmAZw+ z$+oj&o0DEv?~GZI^PJn>V8yjhx2HPo+!L&I=v|z`q#f^{Gyho1tJHXZ_lA0b9=|_} zGd?89^QkH;$R4`5QP9G!X>zb~K^0T_bGHY7c=T4eEvRBNy~%OHbVo=}LlI|q=wjEC z;S0PrEz&T0CAI$7uXi=((?SBST6u;3U%|yze=%^j@`BKMo>#wq)HDBhXv3y!HR0ps z$)y*V)b4tn>J__n-dQcf^kMyrm-lB!j}VJsDux!5|5;Aviy+ pq&%@Gm7%=6TrV>(yEr+qAXP8FD1G)j8!4b722WQ%mvv4FO#p%Rp2PqE diff --git a/files/opencs/modified.png b/files/opencs/modified.png index ca613f9e48f89cd597f9a1296a7b6cd921cb19eb..0ac732ad9183c74307ee3c0d6401631e1cf962ac 100644 GIT binary patch delta 2008 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 II;Vst04OK`B>(^b From c174f57a2fe69d81283c482792b71f71e2b0be8c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 15 Jun 2013 14:40:36 +0200 Subject: [PATCH 130/213] =?UTF-8?q?Git=20changes=20show=20that=20it=20shou?= =?UTF-8?q?ld=20upload=20all=20the=20files=20this=20time.=20Let's=20hope?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- files/opencs/raster/actinator.png | Bin 2297 -> 0 bytes files/opencs/raster/added.png | Bin 862 -> 615 bytes files/opencs/raster/base.png | Bin 0 -> 460 bytes files/opencs/raster/ikony/.directory | 5 - files/opencs/raster/ikony/Hand-16.png | Bin 627 -> 0 bytes files/opencs/raster/ikony/Hand-22.png | Bin 824 -> 0 bytes files/opencs/raster/ikony/Hand-64.png | Bin 3036 -> 0 bytes files/opencs/raster/ikony/Journal-16.png | Bin 741 -> 0 bytes files/opencs/raster/ikony/Journal-22.png | Bin 1087 -> 0 bytes files/opencs/raster/ikony/Journal-32.png | Bin 1823 -> 0 bytes files/opencs/raster/ikony/Journal-64.png | Bin 3891 -> 0 bytes files/opencs/raster/ikony/LetterA-16.png | Bin 631 -> 0 bytes files/opencs/raster/ikony/LetterA-22.png | Bin 859 -> 0 bytes files/opencs/raster/ikony/LetterA-32.png | Bin 1414 -> 0 bytes files/opencs/raster/ikony/LetterA-64.png | Bin 3370 -> 0 bytes files/opencs/raster/ikony/Mask-16.png | Bin 822 -> 0 bytes files/opencs/raster/ikony/Mask-22.png | Bin 1200 -> 0 bytes files/opencs/raster/ikony/Mask-32.png | Bin 2122 -> 0 bytes files/opencs/raster/ikony/Mask-64.png | Bin 4461 -> 0 bytes files/opencs/raster/ikony/MusicNote-16.png | Bin 507 -> 0 bytes files/opencs/raster/ikony/MusicNote-22.png | Bin 665 -> 0 bytes files/opencs/raster/ikony/MusicNote-64.png | Bin 2340 -> 0 bytes files/opencs/raster/ikony/MusicNote2-16.png | Bin 1023 -> 0 bytes files/opencs/raster/ikony/MusicNote2-22.png | Bin 1201 -> 0 bytes files/opencs/raster/ikony/MusicNote2-32.png | Bin 1868 -> 0 bytes files/opencs/raster/ikony/MusicNote2-64.png | Bin 3265 -> 0 bytes files/opencs/raster/ikony/SpeechBubble-16.png | Bin 657 -> 0 bytes files/opencs/raster/ikony/SpeechBubble-22.png | Bin 885 -> 0 bytes files/opencs/raster/ikony/SpeechBubble-64.png | Bin 2967 -> 0 bytes .../raster/ikony/SpeechBubbleHand-16.png | Bin 845 -> 0 bytes .../raster/ikony/SpeechBubbleHand-22.png | Bin 1198 -> 0 bytes .../raster/ikony/SpeechBubbleHand-64.png | Bin 4800 -> 0 bytes .../raster/ikony/SpeechBubbleJournal-16.png | Bin 849 -> 0 bytes .../raster/ikony/SpeechBubbleJournal-22.png | Bin 1189 -> 0 bytes .../raster/ikony/SpeechBubbleJournal-64.png | Bin 4541 -> 0 bytes .../raster/ikony/SpeechBubbleLetterA-16.png | Bin 839 -> 0 bytes .../raster/ikony/SpeechBubbleLetterA-22.png | Bin 1164 -> 0 bytes .../raster/ikony/SpeechBubbleLetterA-64.png | Bin 4123 -> 0 bytes .../raster/ikony/SpeechBubbleMask-16.png | Bin 885 -> 0 bytes .../raster/ikony/SpeechBubbleMask-22.png | Bin 1288 -> 0 bytes .../raster/ikony/SpeechBubbleMask-64.png | Bin 4685 -> 0 bytes .../raster/ikony/SpeechBubbleNote-16.png | Bin 810 -> 0 bytes .../raster/ikony/SpeechBubbleNote-22.png | Bin 1152 -> 0 bytes .../raster/ikony/SpeechBubbleNote-64.png | Bin 4646 -> 0 bytes files/opencs/raster/modified.png | Bin 2149 -> 1320 bytes files/opencs/raster/removed.png | Bin 1772 -> 1251 bytes .../referenceable-record/activator.png | Bin 2297 -> 0 bytes .../referenceable-record/apparatus.png | Bin 1864 -> 0 bytes .../scalable/referenceable-record/book.png | Bin 1336 -> 0 bytes .../referenceable-record/container.png | Bin 929 -> 0 bytes .../referenceable-record/ingredient.png | Bin 1444 -> 0 bytes .../scalable/referenceable-record/light.png | Bin 747 -> 0 bytes .../referenceable-record/miscellaneous.png | Bin 1518 -> 0 bytes .../scalable/referenceable-record/potion.png | Bin 2019 -> 0 bytes .../referenceable-record/random-item.png | Bin 1612 -> 0 bytes .../scalable/referenceable-record/repair.png | Bin 1474 -> 0 bytes .../scalable/referenceable-record/static.png | Bin 1518 -> 0 bytes .../scalable/referenceable-record/weapon.png | Bin 1465 -> 0 bytes files/opencs/scalable/status/added.png | Bin 840 -> 0 bytes files/opencs/scalable/status/base.svg | 942 ++++++++++++++++++ files/opencs/scalable/status/modified.png | Bin 2022 -> 0 bytes files/opencs/scalable/status/removed.png | Bin 1311 -> 0 bytes 62 files changed, 942 insertions(+), 5 deletions(-) delete mode 100644 files/opencs/raster/actinator.png create mode 100644 files/opencs/raster/base.png delete mode 100644 files/opencs/raster/ikony/.directory delete mode 100644 files/opencs/raster/ikony/Hand-16.png delete mode 100644 files/opencs/raster/ikony/Hand-22.png delete mode 100644 files/opencs/raster/ikony/Hand-64.png delete mode 100644 files/opencs/raster/ikony/Journal-16.png delete mode 100644 files/opencs/raster/ikony/Journal-22.png delete mode 100644 files/opencs/raster/ikony/Journal-32.png delete mode 100644 files/opencs/raster/ikony/Journal-64.png delete mode 100644 files/opencs/raster/ikony/LetterA-16.png delete mode 100644 files/opencs/raster/ikony/LetterA-22.png delete mode 100644 files/opencs/raster/ikony/LetterA-32.png delete mode 100644 files/opencs/raster/ikony/LetterA-64.png delete mode 100644 files/opencs/raster/ikony/Mask-16.png delete mode 100644 files/opencs/raster/ikony/Mask-22.png delete mode 100644 files/opencs/raster/ikony/Mask-32.png delete mode 100644 files/opencs/raster/ikony/Mask-64.png delete mode 100644 files/opencs/raster/ikony/MusicNote-16.png delete mode 100644 files/opencs/raster/ikony/MusicNote-22.png delete mode 100644 files/opencs/raster/ikony/MusicNote-64.png delete mode 100644 files/opencs/raster/ikony/MusicNote2-16.png delete mode 100644 files/opencs/raster/ikony/MusicNote2-22.png delete mode 100644 files/opencs/raster/ikony/MusicNote2-32.png delete mode 100644 files/opencs/raster/ikony/MusicNote2-64.png delete mode 100644 files/opencs/raster/ikony/SpeechBubble-16.png delete mode 100644 files/opencs/raster/ikony/SpeechBubble-22.png delete mode 100644 files/opencs/raster/ikony/SpeechBubble-64.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleHand-16.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleHand-22.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleHand-64.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleJournal-16.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleJournal-22.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleJournal-64.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleLetterA-16.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleLetterA-22.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleLetterA-64.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleMask-16.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleMask-22.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleMask-64.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleNote-16.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleNote-22.png delete mode 100644 files/opencs/raster/ikony/SpeechBubbleNote-64.png delete mode 100644 files/opencs/scalable/referenceable-record/activator.png delete mode 100644 files/opencs/scalable/referenceable-record/apparatus.png delete mode 100644 files/opencs/scalable/referenceable-record/book.png delete mode 100644 files/opencs/scalable/referenceable-record/container.png delete mode 100644 files/opencs/scalable/referenceable-record/ingredient.png delete mode 100644 files/opencs/scalable/referenceable-record/light.png delete mode 100644 files/opencs/scalable/referenceable-record/miscellaneous.png delete mode 100644 files/opencs/scalable/referenceable-record/potion.png delete mode 100644 files/opencs/scalable/referenceable-record/random-item.png delete mode 100644 files/opencs/scalable/referenceable-record/repair.png delete mode 100644 files/opencs/scalable/referenceable-record/static.png delete mode 100644 files/opencs/scalable/referenceable-record/weapon.png delete mode 100644 files/opencs/scalable/status/added.png create mode 100644 files/opencs/scalable/status/base.svg delete mode 100644 files/opencs/scalable/status/modified.png delete mode 100644 files/opencs/scalable/status/removed.png diff --git a/files/opencs/raster/actinator.png b/files/opencs/raster/actinator.png deleted file mode 100644 index 0446af22cf7d4238e06d7682ab5ec86127b103c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2297 zcmZ{lX*ARi7sr2+b!?S2`22n@r05bxw9> z^a&3Bmx+@u2Id9;@G%8)gk@vqEIv0)41tP1iIu;TIOI)p00=$@0Fguh_{}UuE(3rc z2mq^20HB=-03u$wjn;5xgZ;jl34%$c9T+u5Fu~=8wDV!EKK$z}kN}Mw0O06FAq;FW zly$VLSNgD6cnjljqh$tyiWEP+dLoMS><*1|p{VYgzjG-~6k=+-Tw27pJha7ule}iJ zCjHo-@1Xm~92G#P9X3(>6-s7(vyD7E^(R zY|+H&S)R1roK?+@EQ}5zxj=k?*TJtLS8B4(0LhYFtdwhEGFBDkQ_??mI8^AuH!gID4Sc&3jLI6eP)tANo{PpG~ zaSm&o4Q=0&PfBZ$R67^YrGvI?xmQh7k17<5#{Iyk(x-J43&iRoQPZs6|=c~?~hpWO<)=%C!K4rHq0*w?(Z zOC7`(HWg9=q|J4gPT|rJLH50I$Zb{m>(J6qH** z;dZl6nk-)HhLtzN`6@^G<#C2L5n2$7PHJ~2W*Llvw0!=N3Xu)rCJ08YJdw$~&q&n8!U7?6S7tH0Um~iLog$FC%$~rzyzd zvfo@`qXO`LBSGVy1fHixQF0gKQWA`A32wqu($dlna2G#U{+w+3Gq%HBBl(zo13KOf z-l!a1;>{F0!(a^q%~^@37a&2P)2x5U9HHq{5;3eeD+()`F}UbtW=56ai4&d2AiepB z0wfp*>a=P(j4yAAP{>$tIkrk|l;De4)8qFz(Q@?cc)uh-_?hU{LPXkv(j{s%c6C{L zIR?AjlX|22uF3}(;Pc|wj0|D=?=wHA#-~&t4V8|3CJ3dl%myEZyjlBQ+g`Xb z;3p||IVMz>-}HQ`Lu6ZGDuU~^h_-l8o=9|iTO2|z%dF(v;cE+%hIucUFb$8ron7f$ z5~lHmP`>0ve|NWu@53V#4+Jkpka>lkP8py7A|4y%eg!h9Ua-cl?9l9-do5%mzS^bF z1C8d5eJqpnMK((!5^oJkOpf|*ZhD4Pgktlw2;QqSh?}%JPxWwN-IuMS|CB^n2h7Cp z_RnlIe0#S(-Smh4XGdaiY{)ABwbH{Mde5LDG*b*3jK=LyH9C*t;xzfVQ@FPv-tI1rlDjxq?EYBlwLw^!DnfrR@Cm1rW$W&R2uH zttxR3)!8%fUyoNlrYE|+g0B*SHCvnK(~IZ0>vcJ99R)9Pbk!=LWFw=BT^W2`26E3u z4GTb+=~JG;p}>3kGNR=`U*p);x$u7SzN{B|&UTv!R-76axHpn}NnkM0Q?fX+!N&7}ZvfUC4+I1RD7!v(^TA=g@XDUvE;$?Uv& diff --git a/files/opencs/raster/added.png b/files/opencs/raster/added.png index aff7e25d460be771eb1c93bf556bedce44a06f0f..ddd9c2108e92610ec92b88676e5e4c172e19944d 100644 GIT binary patch delta 566 zcmV-60?GZ}2ImAJiBL{Q4GJ0x0000DNk~Le0000W0000W2nGNE0CReJ^pPPN3kf;^ z00}w)@MMxokwzzf0pv+UK~z|U?U%7?+fWpSzvEtNr#OTNLNFAP&7A^yflL{@BtxKm zjTVw6Q>I82O3-A=;PCxvkaM)NN;B0yDDL{i{HRhQDq?M5KvE7oMDp$-6$s*mSC0l~hlfQYmb+yDRo07*qoM6N<$ Ef`*;_F#rGn delta 815 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 diff --git a/files/opencs/raster/ikony/Journal-32.png b/files/opencs/raster/ikony/Journal-32.png deleted file mode 100644 index 6c24494166bb710bf1213dfc1eeaa3d788f04b31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1823 zcmV+)2jKXLP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000J#NklN%XY zlwK%z+R~O%3Z>jHB2b`QLg%FgM-i%(BcabIY=; zGbUs+iys$1?8BCg$+Q3e#5M@@lw=?NX~LJ^^Stl#zVCqnz<8fktGQPbt(kP?g<^9j zhfN(EHnwr-ZROD8;gFpghCGvUsxnGFSwWsFN+rDVNY!N7(^pD4Vch+9Na*@0K{w>XPB#Uu1als0ow5HRA7wb@=K=6&iB1 zxLjz*#ex)!Rl0yq#{s@iZfj*$rsSP~q++Jtl7I@Zh~z+#ip^ z*C!dIn-qVD3bgp9v$L{C)%H_6MUjO@U#(5(jlk4C%r!NZx_?Fzkz0U~ilPyU81f zRp9m5Q1r)y;x+Pi#>lZFT8<+f@Zs`8xQT$j9wgw;M;HDVd^-`a zHA;qRs~jUcf^cV;2r!DYAeCg`=CUPdDV1UDSUCFJ>9d@>Z3^sIEy4Cx5^U?1U~8uY zeeDu#X_H`6s{|X}67)7p(9o3TXW-jBFJp~ShCWhy>f8(OAp$m#XVR!1 z`kjJQt$JeIm4k{%HBO}&aMhU^FmMf7GN1Er&M<;=fAIBM9%hYdLR0{C?IHqB+VvPM z&Ip+Hwp?B)JB8CZ?=EBKbWY*x0trYV6}U!RQvoMZb-1+D5pdKzIlK=}N3F}r&MLbX zzBW8S1*m{4#p!~8<0^PDx98L0ug*unW#XC&IA)8(`TP{o zB}3=joz45;bj~}9S-`%RHJmYN`(RDWHq>xILvSo0sD+v9I@#|;WX{_X}sW^!mn><(3HyxY4`SgI^3h2hk&>2 zMnS+HgI4&eq4!*Dx7XQuAAG!zL2askcuODw$)p8GQw)ND-G*=+N{SPO)3mQhCauU;!0mRI7WXd)YKdfMAd z79rnEMzsD#)a9`Ag6GCcVTlp>D5U}hjghEImtt_O1YJc+-(hJ<;Nh}M(cxT#&Qb~5 zof6bII52CBl-~QXh;Z2D#{lo0;~x-~+`B%z*^-M=OP1-`cYPcMd=2TQVD$2ctkQ7hN*` z%1)hAcz+=g5GhgtlSX~7NTZz0v4mn}K8N}|4t2R4R^)J~&E{a$D`1NWo61xxCNrMC zbn@#^DJIiYp~AD1XNgoyrIX#^Ok`1FW>IWnNtReFHIPjh@$A3n{{gTu5zUmfks$y8 N002ovPDHLkV1f;@SNs3~ diff --git a/files/opencs/raster/ikony/Journal-64.png b/files/opencs/raster/ikony/Journal-64.png deleted file mode 100644 index 9bd90bdf0087db2d8d995c0ddcb9cb14e99bddac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3891 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 diff --git a/files/opencs/raster/ikony/LetterA-16.png b/files/opencs/raster/ikony/LetterA-16.png deleted file mode 100644 index dd060d2df71f1580a4e74a45dec66b29c96382e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631 zcmV--0*L*IP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv0005zNkl(mq9$0l)xLkk7XK0d&PKkOp}_{X0^JLjTJpm|_h~3>N^SZi9TB=}-9(Lp`to z0R|m1)7<|{&-MH-=c9)am>34gM;gCX@YlZsb1oE{~No))JFYloX7l+BC7@**# zS0|rf3JSb)3J%%}6dbe`$lGfzP|#8NED4NG=}O!G^0rzifr)AW&}P|Y$2W4R<`3jj z%pS-knLUtAFnu5!XZk>@%lW_fLa+aFPTB{N0~2ll$j@?V=0D_p^fzD&Z8;C!N21Go z{>y|Kq68+~00n35Q}R*9KS8m8%>Y?H{Ym0LSBSMb{+IF6n}iYu;DAar{R9m0^SDwR zNR4!i$q(UK9{*+Sv|hvV2Lp&9@2h`8dX?{gc?ax?1!O2los5U>TVY_7ij~^@m$lJ6 z2oeKH{Fe_jcmWD9c{d%9$w2j}SzOjhI|3vw>#FlYI>6w8l)wH1Su0JjS^)2!PjCA} RWT5~6002ovPDHLkV1i}&4XpqG diff --git a/files/opencs/raster/ikony/LetterA-22.png b/files/opencs/raster/ikony/LetterA-22.png deleted file mode 100644 index 02f35f21cc4ce51977d9161a7fe4f6c4cd27d976..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 859 zcmV-h1El3<6!Gi@s4=T2W6hRh&Qu@R0&N#b3Bic&&`I5~{X1{s!zBg}X z5Tz8-3E_IfJ+<}qkKa!xpGzmHOc2aq#CIX4+=4VCEnwQ1@1a)fzVNR`^bRN zhTKJkET9c}05ZLKB*4P8IybpeV26+dRG~m?%telly6VF-mPij+c|eZ?abUnovsI5) zr2azz3!U}Va5B3LUi}nNFgigQYtUn$4r8UZp$BHXCiRk<93Cyj-vWg`ZtRyPhtgy- z5trF>AYhddEj2cxQ8A9ZtKGh5-T~I1QRN`V4FD0j>p;NtOs)Bz%vPX%iDd8U1Mc1Ox+X_s9#aRp_XRAp*SblQ&CU%k z%=w;A4D5_E=BsEfI)>PSn)NI?7n979K4WGvHVJ4}#*=^k9m99aX9qu6_hgJhaxZaa^GMtj zlY**WR1xu)bxjVr!elAEc&g{Wj8%(~OSV~xkPg3GtW3BeNtCp?mgAkpc`CT!QD7!8 zGIb&)V^VAOkg6OLTKL0asV=6NGRmsbtS6Uem6x{yRLF{3P~URBhyKbY)P}z z4Lo;4w(A=?c3{0sm9002ovPDHLkV1kr>f$#tT diff --git a/files/opencs/raster/ikony/LetterA-32.png b/files/opencs/raster/ikony/LetterA-32.png deleted file mode 100644 index 522bd42547f4c2c26917607a3df29d526e463173..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1414 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 AQ~&?~ diff --git a/files/opencs/raster/ikony/Mask-22.png b/files/opencs/raster/ikony/Mask-22.png deleted file mode 100644 index e7b2310bad24afbbc1f47bd2e1bea4a9714af9af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1200 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 A9{>OV diff --git a/files/opencs/raster/ikony/Mask-64.png b/files/opencs/raster/ikony/Mask-64.png deleted file mode 100644 index 13dfe5f8f7c5501f2014b20be937df9c7fc34573..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4461 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 diff --git a/files/opencs/raster/ikony/MusicNote-16.png b/files/opencs/raster/ikony/MusicNote-16.png deleted file mode 100644 index f43c6eeefe4e9fa593f3402c93c5908fb99dafbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 507 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p>QK$!8;-MT+OL8%hgh?3y^w370~qEv=}#LT=BJwMkFg)(D3 zQ$0figD*u3fyQQex;Tbd_$UAP|KFZjFK5lO%X9PU-t1rM_JrM)m6b8)RY4Y;rdiI6zBB~l1kmv1cw8-ZoOpEde}`WaH?DebYTbK=olR?Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv0006ANklp?s2C|_8Q5Y14hvE)93@`4aA~*yudh_I|C%q^h zyp_$%*F0f`GS{td$>BYOB%ger=XvuE0T}9cUG~?$SEFx{P%AB-<1U@|Uf(Do)7EpW zrP`>+J|n3vyz>m6GN0o9$RDgEexYdXv?EfX(FALRt7o zfRk|SWCc#QgemcLeI0kB-(brX7xrv;*R+SIhrc2&m%W9@{SUAh`hu7=?=5`Qzk*ue z6Qa_bx9}Bp8Mn<3h=|3(VcL^1d49{;TDw6p*P!cBWeFAI4Z`BgU~pKP+8a|gx-*LVDb}eFr892jlKVR+DS@iM%aMPr<+W_H1#+x zm5;jz)s1F_ZG`yJkUxd>AGfyZ>m^iS->QPpH zhEDmEv|qF*d~()uI-hFz`S`BJB^&*e-(AT+-#+i!MJye000000NkvXXu0mjfXQ46R diff --git a/files/opencs/raster/ikony/MusicNote-64.png b/files/opencs/raster/ikony/MusicNote-64.png deleted file mode 100644 index 0f8115b9cfdc6ce479661856e80106781694368b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2340 zcmV+<3ETFGP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000P+NklvT+24hrMY%~n4e&V`F_6N_j%vvxi1d^z(Znq8K|5)jh0uS zC-r*>I&VOsZr_YWS<=7U-%S+aZOZbVfNc<7JPL5(G{9@m{Q$?i?m@F{7%X)0vO*9A z05e_4?D2fhif6jNgWc|Fc-%h?hx}hdiT=0XR8`FF9!rsB)~+w8Fc>K z$!~eiqxj9v&!OFM8!|QRGe#=kB{T%l0KnM4{LDAu*hh+g*zqZ}Sg(Rz=^c|wBtH`p zf=B=qFu3MlJaLa*^Y@Dn+HXOd{U+3#UIm>Z{f>|jL<0Z|-Wg_QPVt*;pFpd16zYuU z!9eAYWox$nT!vd?cd;m@6i(saT?^@|qF>j9| z0g%sN?4LdMHCyoJ6TiU{g7xMr&}<%oLhV7&D>6s5@?_6a(;ylESndDvE>*!hTG|n29PpV^S1)qk$n30C@~LfAYu_FZN`e-_6o=-VK=FhDhf*@oSC4 z;5WVnYYcYm$Eh6!EYLbxx_al{T1qy2B1!V0cv%xLyhiLs7^c&9?c=p%2JuR zQXvumxeOM(KRxlUuy`zZ>FP~4xG%1ir+Ca%$&iDtnkv>FhO)%tVdqi&s>BmelyC$x zRa=2LKVepsgp%Yr14g+!IN!D@8UW}#bLgM!R>xKQbaiVOK%|2vs>o}ntGadabmqrb z8e>uv^%@m!FA*zw;A((@%4IP2PaXI&EFRZ;Q0XYmhf9$b;u=_k$ z@Y2*R@c|%7k;7o@pWOEauiCFrZHN~D*$g^=c+cnILk?E^RMq-Fl06yiHNAjTZnJ40d&oZW&{{If!@HA{l7l7^^dIogHJLc%Swq0-!ct0IXnehPT=O zVOV^n_60K9iX#B%{KJhOu+F3S)d^<^fSLy{0XTppPi%V0DEg99SwD^~Ep~Nyu6NKi z<5sFXWK?+0*eGuSH?B&Qr!pA(w)(4K@f8WrgH2KW-~h1GUY&(59dasbrhNL-(3W!r zwpLt&j`FLpx$J#tFTD)Gk`dUDI}CN!e#lkt0=+!@woy^oivZC1jWr?Gc@$r+d5!?6 zdN2T(C{G`8c`{)C8}!tU!eiS$Wg8nj+wbsShfd#BR(!B*1hx>79gWu@Sa}&5lLsJQ zy%*Fn%M`|bL)H6X@vAhaz^d?xAAprE8!FTN9=a+%f&*Qju`TV+bsxi~yb)ewbN@q& z2HP93&ixiN7Y~EiaGG_#x$+9@Jc=(Zhc%_|vd*LU64eQ?$XAOK04a9f{DfW8zo`2-EdKrnl?yo^DV~e{D($JT z_+sTB34jW50w9l}C)#tbvEp}=(Y+AjBb`U_Matt~mY0hUfRS?dl4eoCAG>`GrKm=j{FJ?`_7&*zsC``MgF@rCp;Fv-fql>j{Dxm1BkEO@;g zx1h;7JnvQ)+1Sjs=I0adp?*gIl!^-gxrX8`PCNp8f;XY7_QPcr@1_om4*x zmObIMx!>arFz>&a!R_-)aUR7NDEh!CD-l-$^kjI+O>fs{4D$wlPI6*(K2y3Ew33V|A+N;?c2Sbt$J4p!=9xg=5Y#(f=gsgI zI@>QM_9#A0`Ur`C%Cg5Fp+ubkd=uWlEKhtI0xK`_W_Ut4pCNq|bdtPDjU-hUYrGfp z{v`pxXp({EM3wm*JIN8sc@%Gx_(3hP_bukj3-LQk0)T&*TtIf&sOp(Y%UP%(Q{aUf zoB66e#va8dOWH{Elm92t=in_F0J|e7>Q`Mo5!)LgXPQP1XYr={nF$3MRFZ^bjd_ zJwl3E%4Z1*Ao2^~y?wnjuUjp(GAevYtc*tD>?8a8Pv-V)fc^u1MIuTaW2Dvq0000< KMNUMnLSTY6KLZ*U+=)p!fv7f#TG` zAxLl%!EgG`&*5<32cu%worY0{L9A7~=}6b}76Isk~1IN~P)K3@?4 z&zpALY4A7Z!>t0&I7qECf*j`WHIYAjW_h^ivJu4lvb8y9VL`DD`rG0ZKvcZ$L@8 zo)6*!Fng}&gE0q~LGCMnsiR8`P)pL0I_sTkS+y)n+TA3GC?X<}@U5p+5=B%JBvB7i36a8NN@4Ax2Wyo=l$u>(wiaH>t=;eY z&gsE1ZB6Su9r*bF&N=_@??8z?#YOMMMu>!LKL4jB<_AEiHz);9}$A+Ax0P=^| zU+r#zA^~C>iUkzeQ2CxnK(WAhdVEVs05c({EM!$`abjMeSb$i7SVF@(FcV4xK=_i4 zBGCB$tYH}6ir-DsEPp%TjWAXK01RS@aBJ(sP$)EA{2GtPgKwS=MwkiON+%F2tX9Ml zjFkW&5X*l6)RG6?SGo@m+@Cmy%*L%h<;>L7dKk(r zKrA*ds3cPS>JLF8k*FMw#hL-=L(!;N*kJJ9r_-DC=M>HC(pEb>zD#Ms*YHE7!@puX@9@rngmHDvan3KH)@mGwbdLCTdjsGdjvb4^Q t3!Qbr#)-P%zK?B(j`YUk@c;n)9sqKTm5v4c+!X)-002ovPDHLkV1oQb&B_1( diff --git a/files/opencs/raster/ikony/MusicNote2-22.png b/files/opencs/raster/ikony/MusicNote2-22.png deleted file mode 100644 index 577e5623063d578900639ad1b3e1d3a3c3007558..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1201 zcmV;i1Wx;jP)KLZ*U+=)p!fv7f#TG` zAxLl%!EgG`&*5<32cu%worY0{L9A7~=}6b}76Isk~1IN~P)K3@?4 z&zpALY4A7Z!>t0&I7qECf*j`WHIYAjW_h^ivJu4lvb8y9VL`DD`rG0ZKvcZ$L@8 zo)6*!Fng}&gE0q~LGCMnsiR8`P)pL0I_sTkS+y)n+TA3GhubkVPfF1P0YZKKLL(5mEM15790x$a+}(D!4qVRtIOliI{oUWa0Nh1ygVQZb~`5q0s|2Tfg7F}I1F#jani|I zF5k0d1D;b0wpKU~+Bxaqlz`!NaAKBzB4w-#6Q8EGh}nRN$eNG=G}BlI5l2>FfKmWh zhKg!H=^*6EaXJOLt zB9H0SCF0K{6`3nm6lIC3sucj{yb~v4mO{bhV5DJ=T~-U6akiW`fxux?-Yu^8NcODH)LOBkC`FC+oiA6!8~rZ3 zyu%m zX(p%g7+Orw)Ht%7P+Ybq@_ONym{^by=MmKGDt`t5s;X8N3ND8cV>GrPFY!keVqLTU z`qy8t{z5|n;n?6z>)}I}l1xMyY2c)TC7U(gm}6jw$Hb=Qrl+3Ta9}$2kef-IbZBe_ zlk)>#&h+l9^Z9%;0O0j{!*gs>%|RP#cKDtP=B12`j8r|m|D;WsidKtu($-fMKRbEq z#I3TjvWQh`7tUX7e=(RCa0siDoSJkPo6I5<9T*Du1^lB$A`zjp{doWMXz_`qSeFDg zD*cYp=(%ex2O1h09^rp&czC#W_s*sVes`_xb8nmIXghW@6bh|1*MAQHRjcjq0Vw2G P00000NkvXXu0mjfKLZ*U+=)p!fv7f#TG` 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 diff --git a/files/opencs/raster/ikony/SpeechBubble-16.png b/files/opencs/raster/ikony/SpeechBubble-16.png deleted file mode 100644 index 131c5ddc275a7090f2ba6e28acaef9ad17beb63e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 657 zcmV;C0&e|@P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv00062NkltI>-8%Ju(V}Vpot^AYadC0!!VCc$psArgd-v}3|6jej zg;n$I+o%8Eym|8fwQI-zU%GVYe|~<(SD6H6ga?O&IZ|h_3BZ0fFU~@WHU%}UtjZoU`)6%027aRa&qiTQZz4L zKI^}_n(BOTG=d0iZOvJrct*DQ!i59>vDw_&QTJb2NpU(b@v*@TP*jlbfoZ;Y@zDP{ zb0+-XxN*t<0|z$#-??+u|Ah;u{I4j_|7&4xx(n!RM~tKlOiXEe_pS%~xvj0{4<8?2 z5Kt@%i1UFs3&{5ZCK_R6jVMVO7!Jaj8A00000NkvXXu0mjf)($Pm diff --git a/files/opencs/raster/ikony/SpeechBubble-22.png b/files/opencs/raster/ikony/SpeechBubble-22.png deleted file mode 100644 index 7b8b5a770ed8be3b05258d1030a9f531b7760e1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 885 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 N002ovPDHLkV1iuLpnm`W diff --git a/files/opencs/raster/ikony/SpeechBubbleHand-16.png b/files/opencs/raster/ikony/SpeechBubbleHand-16.png deleted file mode 100644 index aa7a96863b3add616b0adc070387a606642966d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 845 zcmV-T1G4;yP)N2bPDNB8 zb~7$DE-^4L^m3s900PNLL_t(IPo0u&NK;`H$8Tc$AYx0+urFniFNq(bqCNy#VW6Of zL#O3Lr!95b)TT}|1(%ka^NsmBDHB7J%vNf1vV2)i9Zu)W+0+Cv#DuUfezN-a+`)z- zMReit+B=;` zzHY{xNel741k~Q=qF2s`OvpxlQW#ofA{Y!BD@>mn%_|)9^em;Ml9KN>cx`PCCgTX| zijtsi62Q=&g~ozdDDtDxD9MFhueQSUIWeI^Xh^V*lFOw#bY&V|U7aNZdxH5Kn44a{{v-pcPcx7c8s@~^N$xRV5}knlH7zna7RZoe7sLTwR^$e->;d5 z7Z%2?0;+eNsD6-)Dq%Frvt!VvklHJkKQ6+llU@zPdp$_jtDxVS`;+)WY!5^3Z+l$geC zA81REIk=^!aJP)cVR|*wf4um&ABUMtmP{u86%igX`CkGwN2bPDNB8 zb~7$DE-^4L^m3s900b&YL_t(YOO2IlOw(5whdW>_WQ>%QMIf75vP_4{E-Y&#)65A4 z#BwQ=0Hxeosii<^osA60j278M$Hl=Q5=0^{8v{4R4G@%D3l=Chxu+4vBwW1kWgoW8 z@Z0~K<=?=-(0**rdHTG+_q=a8oGm_%j*gygZf=U8K>r_fCo?7s3eK#Sm0no8RPyyd zdVTg|rBY`0_2pl7adC;Tx3_y+(@8j+>a7>BH32eN0aFqNSxCeuqCDV#IcCfHTm53k7HYe)7aZ zq07tDP$`lqv?4DZs(2Ar3`J1Ig<_;W7doxV3LPIe;=zM%^!2qOG9u&;5+j8>I5_as z8ONWkhb}HoLYtb5>qVdA+Qm$2y3|pCREZGtO{Z~En@UYt=*UPXhKD=Q)6)ds{U3KR zvAo3D`Q{s0v$MliQvzLB7>7DVLZLP18DqwDp*0Vwu}3l6m<^xzyb&c7psno&Sm@y3 zJq!%Ap}P88aJk$lj!Y&su;sJRM~}uJmqbwL)%;YesWRpWEH`uz2@aw>D;l-671Wf4 z_V>5KWNHDQ|Iuv@c}gVH_0akGQKZXbDD;Y6VKqG-9fXQ(3AEB+lWk+)i9do0un9jcH*8ZOvmN}%oSzrgF=T{Rq6SFZTZod#;kPE`F*)u=q3 zY%PD{dK%({ho~um4wObCDJGmYiY>ppyAfSow{Yr|`Y$IZr+xG-fAGHd&n8nV9aAz< zX7fG7hY4t=1WGbZiSV;R^~VBmHdng|T3UJ@ZaiLwb^4eG?WEPH{v^=pX%l_?@^~@6 z*GnmMy=i~32;!suo1le-dU$$zoZGZ7PH0uDER;;t*q8wcQU5iHEuTQ|UkrgVQB1o} z%5S_?i{vE9GgmHGvgHy|D3a#cF(uH^(Jmy$ig33umS)OAFRKMOp-Mz$Wf2k*Vpcpo zJkF7|@WRy@6zJE%ni6PTT@`k}{Z^%q_nwJEzCMdV2l=a?@O>8fA9~Muc(~`k#w;!- z!k4$*#mr9q(rEmRnvyY%5D6!?y=2P)X5GEc#PO7!{e64AuGn(VrZdb|5;5IfGn?;X z_pW!ov+0tphnPr|B_;W52M+9Sw)Kw9=Xg9`0y8u#%pc|U&3OU!U$#Djw~Z_s@&Et; M07*qoM6N<$f^Qcvv;Y7A diff --git a/files/opencs/raster/ikony/SpeechBubbleHand-64.png b/files/opencs/raster/ikony/SpeechBubbleHand-64.png deleted file mode 100644 index 62e4757973bd3093e92dcb29b3b0f344f4e4aa93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4800 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 a!2bbJ-W=X7b**9m0000N2bPDNB8 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 diff --git a/files/opencs/raster/ikony/SpeechBubbleLetterA-16.png b/files/opencs/raster/ikony/SpeechBubbleLetterA-16.png deleted file mode 100644 index d6b486bc6576c9934d419506779babf58ff8c9a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 839 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 LNkvXXu0mjfeXx^x diff --git a/files/opencs/raster/ikony/SpeechBubbleMask-22.png b/files/opencs/raster/ikony/SpeechBubbleMask-22.png deleted file mode 100644 index d0bd2b9cf13769227426e41a9b8394e74d21681a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1288 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 P00000NkvXXu0mjfzLG|? diff --git a/files/opencs/raster/ikony/SpeechBubbleNote-16.png b/files/opencs/raster/ikony/SpeechBubbleNote-16.png deleted file mode 100644 index 0953867493ade4f76de20a589bb2578181ee6dd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 810 zcmV+_1J(SAP)N2bPDNB8 zb~7$DE-^4L^m3s900O2-L_t(IPo0u|NK;W5#&2T#L&TPvVgHmL&FLCTQ!=pph!u`> z;YUIyl!j=oreUclN=c?p#mF)?p%g(9QpC#CR;D$tE1loADWVu+LKuX9Sv{R|U}Gjl zbm71~=icA@JnwT}jXWgoi!5tV;h>Qj)ikpP#*+axQ67EEegUot@Vmr0h5z&Ar}`jcz9S3y}k{5JUwr5n#!AB?R%y$?O7?ky9uVsk)k{X8;w2S`4><` z%MDyzoo2%t7|*{#a!?yoA!eMCRAFXjkSSYjAM?$&!3M)~#K*;$xT`r?7OQOv)1EVf zCrDrw4CeWlQ2I9@R;)vW?{%h3;emlpNTmUfIdTJ)X0wsmPB?ml1xCY)3Q(b|>j{IE zevc3%(&3~}tqrcJDFwNS6C4?y-DznlpXcU2KwGcH#h^i)KiCgVc{!eTwlZZ3D}3)k z?yX_UEiGF3iS|FV&4NVYucc|zo~NeXG25e~eJrrzqC%!j;lhFfRFoIP$J?u(44=SO zz-!;$Dl0rT){lmUT6A)Tn{Wo1R* zU0ht^$k|!4)MQ;Edj%O9w=JOcfaKtonUT6iZIi1R`Qwj&`><0ejIXXP{i%$N9{R5W o6!P%cl^T2~aE%1C{a=gx0N2bPDNB8 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 diff --git a/files/opencs/raster/modified.png b/files/opencs/raster/modified.png index d15ad827c370151b4228b856ae66f209482b5612..39bd182ac234e6e93c86ff489dbaa2ddfe495271 100644 GIT binary patch delta 1277 zcmVo^U0Tw@5^IYVk0_-afTe$b+eM^59zRB0=(bqEX06r; zw$VjIVpdIj3eco=3Sh+JE8Yl<29^UJt;_Y;y^nz2eHL)0AkQZSc|HNo=&_ii5Kjc0 zz#~BRmJJKovS9&0wjOid(+B_xm;fB}c~YgfVY~D;Y!{y=Re)o9PTk80BmlX<^wPCO zn5Kbg8kDYoEdrRX=MrLZ7%Krcu-Qs-I@Yh6dt-3@s<~K6P6u{My6-9hbyG|r6Ii&m zWDf2W*G*O_F4mOH23QDWDy7Wuq7nUz2-?sAnAjl<>%f0E@Rq}2tf>9vU9$XXgB;a2 zTp?%9`}FsR_5&XSZ9pH;8$tVkkcfz>lu8CNu+wONvfkxHJvI&)10(}3z${*pe+xK3 zmOqW+CHYj>oLm7s2Xq2K;4*L#XavpyXMtLvMJd&)fR#WMkQjEBlAMS)!;No3D&CA# zycur19yi{MRAv=qGJafg#BjD=407~%J?ER-Y;9`0@!i;bjjrzAf#w~+s|rX5HUisn zCXF?Jf2iKXMDLi00Cy^9&t2w;7k5%ycc~xv0NCLGdVoKGmMd+Y^AG>@xB1MI`J`Bh z!#ayqS}y#@velpR*Xh>lz&k)Ca3y>Q4Il-08u%pBmu4OM@-+h4_uUon+PX_T{=!b` z{=M7*lmQ2UYa$X-;eJ48f(0xBs>Y@zrGK}7Zv!)?O}r!U6Q|CzxMUX>E(Naw>wv>R zP{LR1z=lMVZ~?P{Jyw#_`}JpQc&sQ87x<4yPV?+5RRr66nt|28&p@XP03CD@i7lPl zu(-XW=k!ynDmn1YZ!v>c*PLW=$u5HJJ+(kFaAYVr42i&?38kDs9#HK{Ovq~g=OYY% zW5kOMfKW)VvbWOJ-CGB&0Dc#do=CP)uVTHR6=;88s^_-B0SrTt8}I;J1)8IQ4@*Fw z2Pfd2`B3IW;9XZ)aliH4>&R=&Q6xyve;vvfNzZQ4s?%e6r^xd9KZ z#02yvTttzP2;>&z`EMM+j?U|B`|w)=h2`u!c)UYIszhY(7hnC_6(}sHyy6huJ$At{ zO@nE&8VAYO0XWcdV2N8E(O@=QY@&O~)?Tg~0bfU#2gAP4-v5 zEYiF~-dIy4*qM++lwL6!0TY-HNZGo1GCkifKnOSiECa>^2?NL`V80KZ2mS=)(OKD2 zwr*Z{-7LTn3jqsw4-l=5Kq+>!;*7K#O(YSR1iTGg7_k0LV00`5#sCL&_$q(^ki=~~ zJoLG;fct^n*j>?Xz#Yjx;#I6flyU(}fm1*WcJ+$s^{ZdcZXLDBK#hoW-C`GofPsAu n`a~oY3-Ay>3Ogc>Xukdj24eh7|BsEn00000NkvXXu0mjfwlhGT delta 2113 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 delta 1733 zcmV;$20HoU3G59aiBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj!~3k}x* z01ejxLMWSfkwzzf25Ct|K~!jg<(f@wR8!|6pi2eqMl@0o z48(PJC28wMfHXoc6l7_fB75 z-+S}kOj{P-q-i>xIrslN_q==0J!cFd1Yw6^7zThS=ffU<_R6(og#Dah7!jaK{S<&{ zA;ff9lS@ZbD_c`QAuLEJ0K+h<025dSM1ef;Ct!tzP>!er9#Ow@z+K>87+Zk>l=xbp z0Z0K)0hfUvfa}0y(214!81MwptZZh0pMY^77Z^eaQSt}5#4%tk@D6YX5WpY6TS`O> zhy<_|0qT{119kzwD_g$-dz5qPgV+*6lm<}Zqre(qA8-#4anlrP;vBG7K}7u~R^lI0 zB6k53fT*jfvD?}m1|q2E*8p#8@vW(pxZTquT9Qfo#JkkQt}9{ld`gL&0K{_*4dUjZ zLt;Zylik)H<&b(*n1=>%gv~y?_{qLLA^Q8pL~pNu6Joc5odx0L`E`ke_~-CpA^Q78 z?#K~0h>|Pe`ViY5*aYwzZ~&-nO{Msvy&bcp$Zs74?&jGNBZ&c#>D;AAU;8^KqnA;zOj*!&Q4$PJ`nFASK>O5*ARvf zLLV$T=C>2V^CciG^|Bd8ybnYgIEh?|ybwZvMAUmDz*6Ml@@Bc>0pg~~*^Ulcl1Y%^ zXugn4h87PHU9yBzJ9e<4sR`s6qtA$?$Q%j{ptsD`!1B0hGThb{TD%)XOESqwM@MM! zc8Jf~+Ni6k0a&3l)&UVirLh=>u>^PwcosMYtY}FlIor`eyv&I~hLZ*=cif$vflN2v04@Tzgb)S20{;Sk0hfRyK>k7|!=}N(qKI-v+%zi|zwy{HEj|Z)2#hMN zQ=mdf<=}bXCU6EgG+z*vivRxFH7$NW@D*|wvV`r32S9C0Iph<568XgE9t6aMWzjlY zd>RM@|^8YjR#+ZVuP7-gv}Zv?6~_yVXTFAh8oYyi4{0CPT0 zX+2zWr!L?{WW~Z%8o~oON*|k%+gWTr#p~gKh#@zPEy(P+)(^tY#Vt&bC6$vzq6J_+wd?} zp-_?d3z-a+rX5zHK-=)J{`@WAXJnak%3hV2Mqbk{14jXCWOS5mLqnl|AzaETW#>*- zp}@AGAx1_=QKCNrepFfuFmt7xR+EhZp94MRK)4jPjshQ3Mi%QL{sUxTYaCS*0{7Bl z9dgfo9a&O0D=aNe11}-Zlt8J7i+Ej?y8&cfON$POD6&4fJqUzHaaZ4AtB~8XF7En5 zczFH<9u;c8@_L|^a1q~sjqMJLOpEK8eY(3sxQKrr_!1Y-7e|Q(M;v$t84i>9H#oA$ zGh|MyiJ1mRGqOCG1w>0SDJFV*h3M}WlYM=nHI>q~^2lDC?$UU-tpc=|;=t3$uqZ+} zT1;7BC$hHc*J9ETd(~=*mSj@g?&)!g--qnz b*VcbxKi86U^taRu00000NkvXXu0mjfXUG~7 diff --git a/files/opencs/scalable/referenceable-record/activator.png b/files/opencs/scalable/referenceable-record/activator.png deleted file mode 100644 index 38306be9e287ff2552bee65d8181e73e770d6b95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2297 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 NpsdiyY739J{{rAiJ1qbJ diff --git a/files/opencs/scalable/referenceable-record/apparatus.png b/files/opencs/scalable/referenceable-record/apparatus.png deleted file mode 100644 index b13982d091fabdfdd498577752844e8342e9c32a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1864 zcmZ{ldpr~R8^^!1VQy>PFv4<(xixl<3-qD^@^p7nQPfZb0I0Y) zlgLt{_Yy8At0$&=XXQmEcH$clrWdBxm-ejqrN-2|K)*t4U%DD zk)nRKo~L~lny{FS46}flu-19L#*F(VS&0wOgc!t+Y4_f;MHsG#4^oAAyGf_Q70Y8TeWd5{a$194nDe&a5mE9s;0 zHFVx2QXGwCP4x@Oc|?a>>!Hf2tnrdB4{qqEH>iGOG8eb2z2>S#qW% zwecIZgJu_ZUSBjYX!s{Vux@8j&hT9?m-nEryAtT5XW z>UPw%?c;RF%;&5hZQ_oo`1pRItJoj*QsfQ3r8v4M=)=&k5>zg{2;Ql#j-k07WU7{) z4rpJ91orcqt&Nmud#j|zs15PimL$nBTXx>!H+4e{v)}-cHJq$V8YC)00+dTo8|M)o z^?(tNc$3-ZUdk!RZqvFWrey9B2sR_C7h=*>%eSD}n z1j}MavkK-R8NV@RmTn1_G<>!FKpX0y`9duZg3z)1_s7n!nlS2P*@JCwLh`$(JU`Sc zjGQjZ>lS_qwTPS^)K!+r=;?tMP=!br1pxQ;xg9s3!-F(VOWp|UMhH<)Xf;R~;wyJS z)nq0a;DUxqolCv+^mXY%e!`a*4|yP0%jVc~N{Xz*r;)x&Z^I7Y;(Qd%&Umju#(2Kl zH@a5kk=9W3VqjqCX3b2&Gm=U)tp6$J^xQ zNe80>tD_BaRbO9MDg`D)_ETtP{P>-gSq=<8wrf%%i! zQ~j6Pak=YI@0x+zs)5XC#F;~tBVoN8hFkEAsO zoSnS8bRU=K2#!wKb)S#vYg32PO^seoWIMLEUo0fYS$NcWXhn4UwT;p*p|0up8{Nwn zG}UR!I8)Vd#&HOS4*(Y}U)d5uSY7+zg817B#T1>I;-ZLOPy%w%ly8sGI2BN54S8P)Gpq=^0 zrPrqbFzD)h0^(bYpS{rVH_;zz2E17Q=4>up{SKHnP+nNst%+CbXt3+>xUM(xGm`Hw zKVG9#Eo}`XvFul#u^5Ey-`%!*boNwixK-2OW(u$s*Xva+QwyYrLqF!Hb1^{yF~Qcf zs9-681=bvAiv7XV!qVIPgtdhHh`i+)?cS diff --git a/files/opencs/scalable/referenceable-record/book.png b/files/opencs/scalable/referenceable-record/book.png deleted file mode 100644 index 3afa9e8aae15c8d494e6e6e338890baffde4cec7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1336 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UV>C6dj$D1FjT2AFf_Cwy$!fk$L9(CXhH%*b7CIvZ#mho_5UNW|f{VYxohp%Qg@@0TuhSh&R@ z>h6yffp$jhJZ;8>0Rc%DBDj-vyAL0kab}~B(f=8lN;792m~>R9Z^e!szMCiX9GRh` z{Q3Mp-C*J7-lPx-p57A-(J`4Tmo9z&_4wZ0e0z4iOrJZypU?X|XY%(w??2l-zsG&2 z|9^GC?7J2wCK0X)2`mgONjwZf&l4CJPoF-Wtt>z9@87)2*0VBpb)|n^oq2L)-OQJ> z4Me09Ei)LEnUvX*E4@Juv-7op_j!COdIwkv_8JYQuMiK;`;OM>C;PpTzU~v zy6aC@Nq25;?yTeA-&lS=xI6v9^Xm)4Rwm}<9}SO>Yrp)oDf=Yn{NvrXKXc#U$b0b2 z|MHEy|0JeOoAzMGKUpqru2p_}j6Yo4|Lwp>^Ei2{Z?`r+?lCk-O6Y0qI1s_%(jt(o zz{$_T^q`W}X`#TM*RKP#rhZsgDaga}XMW9}%)2j+UR$*)`puo`o>BE94;&k z4o4gqB2x6$aWnBVG4wTiEoBjGj+)zR;~V$QdD*7P(bE=OPWpS|N5e)56|0yxF;)`{ z8#E4aoGj=%?AWq*ZMC(I*y(e=;ssm&zqstbZM&?32OqoA+_w2WN3zA|wqF-6^sSqB z>ek;o9-B7*s5p>gw)*?+Z?%D8QDHLgbZ!Oa950eFYKu5z*W|bU_B!1w=jv)7&z8Sr z6c8DDbMx+%F9p38|4p+|d~~svVd1`o?@Ee`H|xbR&e?n1Y(Yrc$4@FfkGAkX&fKzG z<({VQ-LR0&i;EPNvK&7Aetwprx&365nK9K(9rs;-SEzBc2swW|{7&@y&zmZX%Va&lI^x4CdTxzpo9?)$n`?@wswb45mSeLS^M<;yX(&aWOi&YkxrN{1a` zVZHw1^Sby4(o#|_%C+tJGkny1L#j{oi0qB>XbP5*`@gBnKtR2HTR^l$d3Ii)hNj`W zVykcy;ro6Ln*^8mTQRJZ$P|0&VicWn=1@5Aqq<4Qf|Lx~XUMwDi2sp%^>Jan7zf+d zL#xy;1jUB(HXm&8ah-Pf;kMgv|1v1-*t^iJ@3F|kRmOq`69Po#xU={1EHO#K zlZw3yt1qs+n^v_Y<=?d@n;v{?shGR3MN3P|DD1%b;Qdh!%$%QFL|{@)uZ=j-n?&6R{5(haC^jA$?ey_{(D*ZL8S5a2?^Gq7sb=g z6+V6Xl&k-K!l^G0878RyFuwQY?~nIK?Jx2yf4))e`4M12p<3b^QIe8al4_M)lnSI6 zj0_Bobq!2)jm$y}&8>`p$Uxh`$jZRL;}}mFiiX_$l+3hB+!`!rZ#f0jAPKS|I6tkV oJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD<-Pgg&ebxsLQ0QSUK-~a#s diff --git a/files/opencs/scalable/referenceable-record/container.png b/files/opencs/scalable/referenceable-record/container.png deleted file mode 100644 index e54c69af89e72514d9fdcd6e77049e4bb4a85572..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 929 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!D+_~q^pWnWH z`{>c5nVFfhX3cu|@ZqCJkARA2&z{XEVaYDyK4;$Y{RfWk*>`mJo+ESTuV5DNRn(14 z&Z*@Vb!O!EXA|<^mGYL;2$a(ZlGg}U&$k5r@7%cm;r*TW@1A}A^5Waqm*2j<`u6qFhxgAvez<<~>ZfntK7Rl9 z;rsV@-@m{8_VxAGuP?uTxpwpF(`SkHow3AapG0l_x0r#5ep zTEu8pmQu;*=ffIvhoe$1&aRG!HHWFGfYs@cQiMoHmt)FNRTY)qB};lQHuUstT+`BG z5fJAWcksxSGj|SMI(6&VwR89Gox67I)~QQ}?i{=l=osfW$1(8a$(u*7p1phc^6A^h zub;nv|NQmiw@+U_eE00tqc=T0C!XVCVrp)3c4}&7VlL3&;N|Y`=;`X~&she8Y=p< z(eK0;CWgkyk}}?R-{t}Rs#@Y2QIe8al4_M)lnSI6j0_Bobq!2)jm$y}&8>`p$WYtB z$jZRr-A499C>nC}Q!>*kach|WW`7+}gCxj?;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7 V^x5xhq=1STJYD@<);T3K0RW8?x7h#y diff --git a/files/opencs/scalable/referenceable-record/ingredient.png b/files/opencs/scalable/referenceable-record/ingredient.png deleted file mode 100644 index 6b36d008d26b94b7c0c1f1c2d6f215f24ca08c94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1444 zcmZ`&drZ?;6#nsWJ`m#;e8F&RBDz7f^g(Gwq4YruZ7rn;sKFwy8CEH6p_Ga%LP5&= z*>@=hQK5h>h)_@~Ai9Vqx~VY^w>e?rq-@Kkw6)zX*~+9HIotN zyUu?d1VO%33XuhJ(8^xp1tPIaJ`Iw0E}o8uAX9_S`;1kf_7Je*Vxj)~A1|yRGbt=O z1eJt9khB7V9N;s6t9F9FQ4f zi`!vE>WHd-g2KuYY0zRFre-j%q8AS&73nec!&KG8O1nUXsv00RjwFC7Km#~AJ3tbs z5I|?$5LI#xD>h((NWK!qYe!TXV^4QQNu@C&ZA8r=rDcpE(qW1_A{(#LO1t&}hK8#N zauc~gfhf|V0Y=&r3L@YEv<2;mLQMo9|N4BCK#eMB50`fDmlz@iN)%uy>HHUfsWDT; z`bdE~0+3Yn#MYWA((Y)`C{Tt2KZPn(u?{2Y+*e}2oigBnQ4$ahI51kMLGcubLN%&L ziz(Eg`3iKQ8eOD}5VVH3UuP<VoNvF8sG3Ns9il34 zCdthdg*6fQEH}pi{cYEniW`Z*pJofA^%}Ef>|hHZ8CtQc+C*-)(3?i-RRg3Z3%#aI}1^SM8j&IL&(WHFLJ-kvVIFmC!{Z%Mt~?jm|?9WLc( zIdASY*@Hq$BW0$-^|}Vxl#9i zfwms8Chx?3HW1=*JRyzp&(?_$jv)_iwNr!1i&kY2ucQ}JhcM_;~W4gw6 z(OTOGinbJ{*1OGSTVk`wij>6Ua;oT{{$XE#S;)YpM;jC!xW2I?M^-1Nr{v>~o}Qku zoh+tcZg-G6lF2&5d`R+`o)cm~FN3G2gs$VqojRSS&V#yRfd{9b9f zds}G?XGvQ6+&t!bocaFb)#e9`IUf{K6=6k=u^34sV0*#dO`#hat4bLJjP_hwB|rNvQ6{@|41(x|Mg8-lW2FJ1i0zIVXQ?G%zyg;^QGY+NQk8zcw; z4@bh_Xc!`b9ge{vz(Rz=5jZ&fhqS!lvI6;x#X;^) z4C~IxyacIC_6YK2V5m}KU}$JzVE6?TYIwoGP-?)y@G60U!Dss^Zy@@{=eG)|JtPgpN{?i`||&{Q~#eY{CBJ7|LwZ} zua^D)aqs`vz5gHd{(n~T_io|;`xE~Ec<}%0zW)z8{y#4Gdq4mGz3%^iU;O`e`v1e; z|Bnj(-pl)czyJULSO0%J`Tuy{zh||7AJzVUwBY}3^IumT9v^aeeWC8n#imCG?S5aj zJ-x>0?+w?#H{Ji<^!Rfp`tQS{zt8*sKgj$0v}xZ${T;K-ch0f=ddcJ5M%%L+tpD7O z{QDs9&y(iA4@>_(p8)hudYNSnkg_TX@(X5QU>38oW6=uPxhYsKaPr4D-TE2({{G#q zmwxo$-y_ogoBsaYz^qpD`*#)d^vi$$UXJ(@7Z*6~)^k4TvPuR!pec+=-tI089jvk* zKn`btM`STDW`2V(BX_y!Y@pyAPZ!4!i_>pUxk@z!NVGoW){sbOU}Rg+#K;!wwfVoP zWx#mQ{&{c%6UuqIPNT3vuaa; z;exzbyO?Ev2v^uYXk_^5D8XiTNaSeYmAHKYp$6@oi!yY9?o=&tjVMV;EJ?LWE=mPb z3`Pcq#<~Wkx<+OphUQjAKxCwCU}R-ra6eKu9z{cLeoAIqC2kGtSe8BpYLEok5S*V@ pQl40p%1~Zju9umYU7Va)kgAtols@~NjTBH3gQu&X%Q~loCIGkaSGE8E diff --git a/files/opencs/scalable/referenceable-record/miscellaneous.png b/files/opencs/scalable/referenceable-record/miscellaneous.png deleted file mode 100644 index 37862d3b54f114d16ece2cc31673c367f517cd2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1518 zcmZ{kX*3&H7=~|XB4jMJ?^RXQn#Nj;rDCVH*p4k|NC;7T9Y(0?UJOGUY8gv)YP7Ud zgj%Xv%SakjsnVdaRh6J=&@u6Ie$037cb{|b_rB--_g(Wi=O8R3F9ZM(c5*~}@u+gx za2W4SOi$nD;YgH?n+*WX`H1~6DDMqP^l~^0nrMnEhsp>?FE;?v)d3*q0bA}<4w zj09j63xL@j0A%9Jsh$?R0W93b0nHqTC8B1nFnSh7jid>W%b;t@M2uREFg^$0lxZ@o$_WjC51|M`l@2jStV?6Fuw zI5L5&`tg3m&>s)h1L-Y6F_J-qS=vB3IM>QhnRA0m^-zf2^%8syfv=>oE+ytdisJFG zNdpZ4xlxP_^w#)sf0}SS1`}MWtYVs$9ehLn%$=1ji``?hy>GjWjp-K=#n@){vH*Vl zlmD|U(uq^#n58q*9|jr3ERuP>*S0u zd!(P+NUz9&1;HdIe<)qf*CdOLBjTTWs%lJcvV`AEJ39)}w6EzEm0#`0QzXEV>^p%s zL%lI9;VOjA-09;dsc>-_zO3r`!W3oKTNf0w@$YGEVwgo?rgJnU1=(n^Z7(5UmqpU9 zgQ75hF2C56obS&21c{G3L5UyRy49m^)>BklJ9MCkHm*694*}Jq-A2iy3WO+DBUrHX zRa3mp@5(Sq6}O9U>H?|g=9V{1)6EJNh_KuLb z#VhbEIS>AEzAbV>kF%;$Uk0016@ZH1B1R^zg$4N7?~0z+azE)YpB=XB#;|5?235a* zuRc{Ii+C46Z3=8E+qNBLJQXw-Ym-HkR_uGref?IehAa68P3TGcQdlq}u4O-M#eC=v z%kiCLYyAGg)HC)sbRQ)|oDbLD^w3Gp-QU+xTIgQ8Z*(VzVO2A8rWLz7+(msqT4no2 zR<xoni*|MVO_Dx)$_FmRE}nmjY6u3wR()?l)p;-Y(PMYv8SL9~`;UW$ zxQk3|ozNAB*KVQv{Vsk2QIvi{<_+gzP^o+=2J%MjyWxhD zth{LEFDdvnDX6`W(JZsY3zo^!V#lQj&0snC(B(|WH)xWY^_d=sWs?7YGoR>C-RkAE*r2~HxWgQ z#Zzi)iYh%JWs#Y_?so|jetwj}k}A3&!c9&vu;apsmAx3XCe91HsFv=Jg$qV;l(i4kG(I6YEARN1?kfXbrn38aU{- z3sU@{+<0a!iv~)rl+3Txa7cH}>dVSI22GKaO_9M`AyN6xKhB17CJ37s-lq`+%KOu; z>D1iZX0CnG=k3~O+%c3lG&+eq$d(kBj8vlk`-PRb!FEyqmNQmnj)0NzYvtC1`^&d< zC->wBkiCJaq^a1@6}F@97V1e2tSk0CDr7+MFxJqfK#RToW#~ctg}9l=>ci4KD)g^e zt)H(|00E6J7wfx{7T<=~?=9U>)Wtb5EIJo@v(iwvlo4>Vq{|7ksqx{C=`|)cFkwR1 zziVbFRao+^K3}h#B9VLCD0eDk_?(2eTxq(uE0w$XVQp?b0te%x=|^31r6`$3|K5FR z_+!wA4oVeBUGA*oj112;z4Myt_k~d#IA81cb_PwOmox`tPCt0qaF4SXaS#$|@aS0h zWKPpZ&$E+>y99G)^8DBO+g-71Z$@+nJQD1MfhJ$Zq-D#3Wlm>t*t_8NY^u>COc(Al zk^9tG@r$ELLp+xwiMuoSeIu^>nVd(szrVj)`p2s^^%i7i!sqE}?NEVf|C&oHd%KSn zCfk0NGK~`Or^M6*&BV(1%%rVsJr;86S|ZkG3A&81rS`jdC&}D?{lP*diaB?A|JC=_ ziQlXtiADJohx>>ZIFM*T%85$VHudV&(#FP)*0GMLk_-E+of|PVg7nSho!*DFUPp{P#WbH%)Ewd88NIPU*e6bRyRW=Yp6%^5(rKH2o69K{J9Kr> z0|Y&U6o#IjI&S-eT7m|HpwJ+%D~!!4M*L`}E+tP&-c%V@`uyd~`}qc)qpL5IbSj(%0c` zk#|C5UgG# zsr&l30%!O?i4AQ5Vb!q-J^;qYVDjYz%!n%TPPG8cyh}Un8AA;UiNQ}C%2$t&O*1{% z-_I;=)}p*Ko~-*jgALjhgyYI+f>rE)r644$$(NL{Hbk-bQ+}9!MdE$+=xk|hJ3|Y| z!A9sXHy8u_4C+u3KCaxE)K~T7TU~HjrNFGW6D=Rz7_7q_cF^{n3K{TiF%QIC))u4S zXAEy+-#{Fag&^to1o2+@Vcbi1K3aY{#@^vBTvn!v)`Etsm!soLH(IP2*W;b#2{9c9 z&vpuQ2mTb0V|USN9L47iN^&6v#?YH;ER^cl_`!P_G7|bd)UOBJb9=r_J?4zlg%2dt zZtzQS0COTKDWaTd=*=lQUfP3}TypFh+H_v!kf^EhEXVQ)7v{wyb zo+5!l8*dC%$WJ^YJAhyNlGjYuclkf}&2U9mmsh3|FU_*#H{*RW&KICDPvMtQZc-V` zXsy2LO>3s*hQMCuv^H5H^yll9Eq-;^sgPH~|0c3kC}*`w$pnd{MA3fJph0s>lNKCt*UmFm z5fB!J)!eeKTKGLyU?0D{O1QnW{f^P9{SQZ&qUfx+=Om$Q&dee83`9=F@Au8DcTI%- zx>>?T7)M7V(_|c-Au5*FmR7S`m$$YgRW9}|@F$5)jKuyXN+_SFL9%+x$D<>l6?6rL zfC>wI09+O8L}L^vTR;3`HZ5+C}AW2V3p0rs}eHg(8LDgOcfo~TFw diff --git a/files/opencs/scalable/referenceable-record/random-item.png b/files/opencs/scalable/referenceable-record/random-item.png deleted file mode 100644 index 9f1367a83da612c08e365f059b6f3e825d608eac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1612 zcmZ`(X;4#F6uyB3Lc(4G1;dV!-LM20nj#=!sVv!)GFAwyM2aAUK?U+cKtXJ$RH;R@ zGc*Nhg^J?P4m49O6pB<3Dj+*$QG-$$kYxmfo{&yw`lDywyWctIeP_A%+<6z+ks&%H zGZI2bCoD9G3uvW$iR!Qh)s%Gt;ExAH1R!+hGxAnE0c>10HzW|<>ZQ&rnTes?2!zhk z5Rw!lv;i)O0-+o_LN5de`Boxil6k$A!$e3ei5<>o0Rco)Q`5}MOr`7S==k~hH8wW( z_xFRYast7|#wI*Gyt})5XJ;opJzYyn3qEOUYa1CERaI3jEiFw?PwVOFkw_#mnf&0v zgYE6@w6rwfSXfwK7&baOy1BWjudfdtS6A1`$;q6Y96FsoH8r)iwpLhJ=;r1Y5)!ho zurN0_2YI}_yt=x&-oAYs5dj-Q=H}*ESy`ai+S*>Za^>mMrzR#Q^YimtTU&;PhK`Po zB9Z9%^XF75RV)@m10Eh8EEcP?vy(!h;PH4LA0LH6VPIguWHPy2?)v)r;^LySvvYHE zb4yFh>gwvlhYx3FW+o;kyuH0=XJp{uL=v8E_n31MMj;2{tQDrazTus|Sy*+oS~shHr0sPXY}AVYGPwJJFdhl`Dkg`1!< z;aF4(tRPO2cs+n_5jT>D)E$$w4LF$?7DLdqJ6eEYVk({`5@T43WegY=sh}Ryh{MEj zP*^Exal0Uws$Hoo5 zhF#$j4uu4vQi6FX7+RU3G1+j+%9Gy2k#iZ>fG`#o6u|fSJyGC~f@vwn8sm~LKK-ib z^2I$R&U*VT?@6kwtIO#}ga#b9Q(6J~%ONrI8o9A!% zA5*6hzV@u`H%b*2b>xUvS9JWf588SXI%!t%JP)|7$dHRok z`COA#c=;~5OM_f3clwob@|8V_$%qt$FML_tL$m=WY{+ zGB-DBhbv;c@3*wKJS;dFTl(z0Z06D@+_5Hm;-B`7rGdQryciDUI`y13n?mP5`4<0V zhR2R>EQ-S=9<;5J(#}6K)=xcmGc|3||44b?NJn1*34gYlbUH6hLfY8aXD6B47g@zj z?&jZ?3VAoeuj=yYi7AQce0j^8h7k@Y`&sX`dxGgUmVi)a?D~-$U!nNYwf>lHxb70i z>BucL)0Pb*Y6EWU&d~S9l`}(o8>em?B+Sz)w^E2xCk~}6hSJA!tuBp5mTtMei>)ub zpSS*3$l4~Zd@I0by>Hq!HSFrN;yd1NqAje zyeQc>F)JAWxzpV|T<8oJcQ3x1x34=qo=$XkUpifW!9Mvv0qGe@!jv=rAJ8*UJ^}%z t$_l)U6j5$`Rx--X&2<%?Ov_G;&rEjB$U1)Q71InzD2x>ubSqFG{Tq|8Yfk_G diff --git a/files/opencs/scalable/referenceable-record/repair.png b/files/opencs/scalable/referenceable-record/repair.png deleted file mode 100644 index cb631d233766afdc6a058ea57a62d44378babfd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1474 zcmZ`%dsNa_9RJzEvU0V`mQJ_MJk6T35T-ezLgb~18NOfT3$c8l1ez}d6af`5!9tLu zDVgRANkGx?m6j)8JzTBYX|399oqW}HPFl9>I%lW-vG4iZ@9TcQ=YAho%$Z5Y#SR|275&Y>QJAA{J^Lw|~A88Aqa!At?JB z2;vk%&?0bgrXh$0hoC>AAqb^_pwH8)Oh?fWw2JTV8;A!1L>~gthe#sfi9RbJc;j$H z9DzU}67hJF7XUDEL{BdQ28+jftq>ONiAH148QBaDKbKpS$1P$P2=fJEzDO#N%1UHs z%am$GT6#*&1+}2GAS5EVLRHqFtpm8!u4(SL*k)|fcWX_3hJkD5p^^TK>{FnOh+`qu z^-4{1wOA%%bF-7_iT(k8{y|4_IHy|;jj~D!otf<8L)^7%7bS>NSuNLfwX_-d8_l|eq<9PlV`pbaAQ93S$s$QnZDTbKhwd=8%N1uDnl!3v zMLaFm(4*BFn_}XRJ2^Q;MTZH*JayeUWsRIulp7Kr5PmE)G%^U(cACu!j|w9nJ)F); zIYJ?yq|<20)PxhUaS6v0lH%ChoI)Y5L?Q&7nUS8E&17Vz#wSK6rPI<_$;>P|Xbp)( zzW-+*Zy*RLfP>vEeZ+zJ0UtX*=>J}QtQgE%ovFFKtEs)SN!xj;%?QxgW@rSnYSlNi z=r48;=!Zx9FL$?e^t2j#+f4)d-eJ?wX#d#lk;$piopP}k(t*uI;ghy0gk! zxvKW8T60c$UM{H+6_*wAOE{dOoE&b3L@qM*8q9+xwMM}%%*y9y6^PhEX+cT3KqM_F zEY8<7)m$GRymfc{_T7oW5wpHW%N6AEgn3||r80q}qF7cb7L^qW#N5ul%gXZ=LJ3bS z7nWC+f{p-5=Ow*B$e0wr0Ep~IKJ4S|O(fuPURY1ep@X|O?n5FF2v=7)9GNvbfc^E= z!uy5 zItEiuFTeYxOxd#PQ4Z!3qN=J&B`@OTGE=jq^=-Nis>K@N!Oc7buJ+5e`Guc-yTiId zj6wQ99Yx{4Q)d4PlxGopn23XfFb5JatkOtf;MZD%4OuT)tj}~)fdHB}&NI;CMqKoE z2Iq{ZvXWmRRu{-hRDyHT;~0OTXDBYvHxf(n2`2>mu@|;(QlL^6OKp*~apeKpOeD+_ zzmsYcG&D8laK3MFOUYMPdh&8ZFr4Z`t(>)?FiWn7*SCpo+gCp+ z`_bAeYJ+9W<9iy%uj^{>Hb)uRgTwkSVq>2$UAJDP-|wNmFudHKF?0V4ZPxtGN;JK$ z+}**W^Y_Wejzp=$q4b42&ygdE3%h9(RSy_!7^$CMlCw9;TwYwi!{vY@(s{qrzP-IQ z+J;U|N3(tYt;v=?r-(4vs;N$!JCQJMxV?_WV*MEnv&IBFZiA7>#$2LdAu3hG1Fh{% zw#}y~ZNx1r+3dix>#4%rjj8n4yr)ZZeBAq~rY&=Vr&ql<*+H5&6OGN5n}fj~b~5py z%=j246&1&z0s$f5u1FWSn+w7{&~+aQ0pR8gN1)(vyJg3l|4B%p$Dc^Z`u~KaI#mit uuw8i}fS$n2jA2lr%*@O^CsLD6#l@si_s|(M)ePDW1VP?-KU^y|n)f%q0Dckx diff --git a/files/opencs/scalable/referenceable-record/static.png b/files/opencs/scalable/referenceable-record/static.png deleted file mode 100644 index 934e8e2980b6bcc86d4292799c3df52f58ae156d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1518 zcmZ{kdpHwn9LL{b%&gfmn#*=Haw@FNrRJ8#YI71JqIE$CxoxPmRZOwAO!6otBo*cK zOjeX+l)A{^qE%f53Tc`lY3XJBXpxQSiJ(%tTYM)qrT2w|eg0}#`w*x?s1Hi2I zOYjkZ{UiV;A^~te2f#9R+1(&d?LdFeW;#tvZE1Y(Woco^W^7N_M$aua#E9!!s*P** zqftY`+rMsmn)-r)`MKAV^Oh3833`L6zs7XE867+53*nRAce4CryqkdE6_{C7n;7PClL+D-E2N-R|f` z=(P5-i4npb#P)wwOL`?AaRB9v6&z7oofD}Bo6jh=+l=8YM=5n?W_MKc@@JFo3&Zg- z!ryCa8!bC1hd+5<9F@wQGPz zt_*7Mo!^Y$@i60z*SHn0)hm^XX58#hOJiauqBxj|y3L{LjZy@tZ}z6ix~rh*?DkWa zT}LU_1ee76JLOlbtqD5LzAUqx1bEh=QdfPX_u*5e+{pvfKb3?Yb`0ObB&?RLd7xWZ z2LV*jDrw8NY?_)dweZfIerY9;u=iAW<@w7PXF3b^e+p&Zu({T^wUH$!wr$Jv?K7Qq zL98^cXTiLTE61y5;hx4fpKo{;AMd?X%)-|nphIx_k3Hy4tg!xILwT@YmQ`}X>8kAx zKK%`KW8;PV3y_#3%YM0AmyCQrKs@|#Z(NjF9=5#XdE&^}2tjujfm2+}T=))6kt@!I zx>SVk);EBJhK0o%2mO)sQcd~3jL01AHZfme`ojcz6*<^4+5hlMi8Dp54l*EtgV>T1 zDpp8Q&&v%=I7!!{J4yUmmkCSDPjquK!GebE<~6ChS;)3cfq$*SZtZC}B*{r=>l%&x zkX939Sqw!BNe=b{cBQ#Y_@=cUn7R?w<5CPCPe03e$k8L;ijeNxaH0@xeh^P~7Mb@n zK+%=;EkkxV0_+8Ccn+XN=4nX?Cj9ZhF4~Y`J1|=AGc+zLJ3TjZ{dE&J(6%A4NW9%) zME&Y|NOM+%U8D2K{F*bSwNmMW8zIw;e$8Eu#I~~YmwH}Yy_uIC?r1PWrC>$*kW8Tl z$G5b@rR(^&y9+gWN)ZJn&4psZw%zqET#C_~?Jq0KIe!k7`?>EBj|yXACjdRLto852 zzGrI9*0+`K?MIILR|1=}CQqt1Cl5vm)kk=4l3T2w^SpOqtG^UK@=Bu1pFiJcj&+?ss|6r#0jTz0FO*d&!sCqIeVKyCF{v)h(O z(`DutM7Q0HPd%~=`K|J6%r9cL_fma`l5q~}vn{BIE+5Uz9lNcvcY6prDjHLA^M8XX zmZK_9!%DYE!zG9D4tnz}X}KFZ5__}+-M|`PjZO7NiN*#mJnJax7G3QBKyfpy8lL>R zKU8*4w!9I)o~DQINbEqQ?}NWzw&wd#0e)s>`AKQ9!sOATrUfN#eqX3<&&3L9uwhBJ z-e9%$Z%e{klab7tm~|f6;mIO1&Z#XE(~0u zP+Vc`7q=)Cn*3-?4UYb__f++&9r^mp10KnK0Bgi$$8j1#6)Gpx<{wQY5|-`WM@Z`tE1D}5b`>AC+%5lPjYf6k?hUf z{QqM}PK`;}%lm%=YjgHDt-*XTVQcE%3~p3fEZ}mv#DtW@^ynydEHO1Lu2ku1p%nqY MjRCY;pU9*C0-JS>N&o-= diff --git a/files/opencs/scalable/referenceable-record/weapon.png b/files/opencs/scalable/referenceable-record/weapon.png deleted file mode 100644 index deb2e50bd181c1b12db3b31b666f96d84d7a36ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1465 zcmZ`&do+}37=K-66Or21rLnU#wVQ@n6yZ3cH8E?5L8aRogM@}4@kNb)diuLFA+*eM(8b= z5@r#KG(l+22O(l+*#?C9v|?(QBL z8M$-kjz}bW`0ybF0ZeIWsob8GmDSYL1TvS)t*EFN8ygb{1R%V4@#5*zr^(65IXOA~ z{rz2CT>zM#o^EMr!Q=5_vACzF$Ii|U@`AChu8zm!K?(>yH8ln9P#%Pxn3yOkDypok zoSU12$QcFMdSv$HS+8jS`>sO0^}9jqWEkx1k!$PgBi!fsYS-U0 zJd`1a!F-^Swzf983e8SVP6CzVtE;OaLVbO`T;*^$a8*`TCRbr)X=!P4xh}V=TeqU2 zg8v8MHus!mikA*QOgGJ2j~A*373O?rkRPBwK0aO?j88v>Pxad$dz8@G{ummRN~KT? z%nka2)bsQ6P!Dvyu&^*QGXq`2G#~{$=esBBf&I>;x_Y44uGCK`lSI?y*I47FwOLyo zf~LYAS^uHA`H@QF-LHnQ7J(fr>|HNMl$1=LJ+@qwC=1pnK9LNnG>6-%NwFaVA%V%A(ITu%O^CU9^FsVm2DaAw*!cC@fd}-NL&4ZQ zSxrOK-9dWoGu+RD=8?G7H+YI2%tc1gjoL8IhmW3*I9 zrrWUW7a-9%aA`iTxi0#L$t5)nZ7oUm72=3T;@Gw87woKfiR`#*PJ-KbeYcFA)T+B$ zZRPO2Z6E|9-gX0DmkqgF*e8yk7!;~z-m9r$C0w+A6KQawH%?h2MyPl{ZoQP4kA5mp znReycV1^HS7|1$>dD6WBzHei+oZ>AwR%aG%LL_GITeC5mJx!#(Zy2w)s;Hyw#0K~!jg?b>^-{Q;b7lB2`ITN`4VnQR8y@p2H~~;}Aof zl!)l$1|%vh;X2;M`?!|b$0K}=Z}1b2#Zk%PJOW-t51*l1*w0&dfS<+D$fi^Pao(?@ zTi3O%t*xx!&CN{*2M5>iCcZDuB7~6L#QEOECkSh6Yay5Q_4Oc5ncL#@TP(?Cp;-A# zLMxzYS^-Vd3TT??gDm-*Nt?yQ!2K6Lz|<7R6lM|-Ccde2#+WVPm2^C-rvYo$#P1z( z8r8UoPelNC zY~fa^ncLaf$%@(7*s#01n-!DH9C1DMHtu&s5B?|a;>KVw=%$PQSN8Y!?d|Oqh2kqQ z=Wz!o7~orcEY<@{Gdek2(0o*q#TmZ959TXq{=%=KhyhL}Bk+f~#QjiSNy+&I{3wbz zlu=TO)!DccLI^mis_Ix=;-0str*KL9A3PTK3Ld58X7PMcKRp{y%(cOgRuASW!slVS z)f7UQN5FGj_}geJplMnGP16c!n)7V42JvZVI2_vE-p&d>Iy#yhjudQgKg*(go3+M! z_$4J!(hl(fURSuyS~>y&PefC7M_gB}Gy6Eem*Ot{6NRI2;a~PB62Qyzy3OAq4O5KW S_#Zd`0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/files/opencs/scalable/status/modified.png b/files/opencs/scalable/status/modified.png deleted file mode 100644 index 0ac732ad9183c74307ee3c0d6401631e1cf962ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2022 zcmV zCAcCHS*xf4V-uEySWUDsq9lYr2r)5Wf(G>uW17V@7}$-3tO>!eyVkA9AB~`k*IsS3(9fsP@ywV4Fl9#^Mx%Zy$IrrT2>pdePgiXd61NcA`FhClZk;lL+ z683_YJfH&j08kG69vBB^!e;ci1c(C5fo}t4z}J8YV@x*eT?kzOV~o>&3-EDtH`W8U zQBw+4058nNEJcAjV2{1`?R}kn4wXU`z-m7ZJPT~f`zZx90p)f~XcYDi_`nii7Z7i0 zX`!X11)v1@0#HlXW-B70T&TNz26zs*14vI#kM#8P2x|9Zz{l(u6B^$T1&9C*zz+aP zBodNNrzM?EOCphQLi`X|2}Hu;8;S|pz*PbyfzJSRb#)PqMu|qFbai#Pp`Qj4K&hRx zcnV4TKI-?s14u?10r|%nGmzptG}+>gwv;nCj|k zIy*bv<1U~ch=sBXA!y%2ef*2SjPLt0G&Cf$X=rFjeBT!|op{mC@t*1-Mmd)>7=lz*l3?x%r_F=htH7@)=isRQ1H2BYP`QVaGSR_m2kJ9DN2jg5^A4i4gZ zg&kWqo29wAnHx85%r|5TxQEsc{{lvVe*$mi2|8-8zej*(;3YId`USZI@pzm>B0(~l zB$-U+?o+8$QSbns=W+Vg39mD^DA{3=9lNeSN(H ze+SrS6r_E?ttUswxM51o$HAXiBlJbaotwqVDl| z;2I#YSWJ3*d!IP?GiT07NlA$VKZs_s%b69u=ZdthrhN{06A;hy+PYnFYlPAUV zJO};{Xmenx#r9C7o-bvHpl+-k__bX~4jw%C*uftV>r*49QC z6`}9@w6?ao#~I6G%JM8q3#o}+uxkX^xN+kGrWU3R8#cJxCd(tRW)>oVGozL8*aTQ@ zc?8B4XrS#LM9_+9=`5y;ro6S5Sssy~9gCon8Z>!&4-iczlhoJOFBIpz)Y#bQ+AyW4 zi3T>KpaOVkto4!H5Z1>Ot90$~d%KpEQOzYWO6ix=kvaryFP zNu^Txxy%^wZ}+@q%NDtI?b@7k&z?P-pEiFOC=Epb9<GXpQkf;9J;=50K{OW;uWU zyoiWw-@e_g)kDDd2ti)=xB%7!>M>HO6#f1E?)SHWp8>A`f3tR<26C@djWKDop1p_m zcz%a=slPNhI9R=H+cvgt-O7?BxlYQv2^!D>>_8kXD(>WI+u8Xq&}yjxO~4`)uv_#z zMJ%}0z$bxUVf(6i*KO2klr3rpY&49b-8t6~nn7LNkAOb{{{a32WSqteC`(XBaL1AhXx z0DFN|=&rtL`987$pc=mmd>ysjx0u7uAB99DYmAxV!TGoi{04oSnI^!u6{ZmXJQFHK zcfxgwL;vz5?+X{#&d;Fdte|NY6d-S5msm;Iz!%H!zYAf)#yFq2ng9R*07*qoM6N<$ Eg5avTxBvhE diff --git a/files/opencs/scalable/status/removed.png b/files/opencs/scalable/status/removed.png deleted file mode 100644 index d4b0a4897eb11d650f2215bdc9fea6cacb45c840..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1311 zcmV+)1>pLLP)?J#lKJ(!*lTkefSmXYRG*rV=Aru_F82_c`a>k8`dg z5h3)6q9_88dA{thH?OTI^m|bhtpHc_^%8g`BCqBeJaxpX+WH50843~v5Jk}yU=4T& zr~{|KGvMz~2z5jacw7HYfeG*;#FjUJioXVY0Bixbfn(rD;1^)#JFtph2i^yoYV&8{ zC*U_=>J1?xl`ql|uLF00N5FGHfTzGvMXUoW9=2A14RydC@Q2#^9XL?uZ1~s`k!k=H zUkA2PH{FaJL0BN;aG8&C!XJ^N>b)XK}K+`-Jz)G7VQ~Yc;6A_UlNoAHp%MxfgsOUK+NK_2ZZ!` zy`H@hM5k!p@IfUCew zU{@(GWZ)!87Pc`SkEPXWW#UJ`7r=YKsu&T7baLF%Jeyt=#G>Nc?Y6x<-zGi1p3MO{ zztuN^hnEdeApSna1}TnxAlver8i|w3fS61s(&=>UJ!Q)lp98QUwscazR)_-e_bEFh z+W(MCjKpLzk#4tZir*_rn@Rx5M`Gy^1>zr+dA<@r&Q_;vVlOS7k|dE{uV?3cspq`_ z42VtAgW0#}(cq#W3XUG%0r&8%$W{n@qQK8D^7wTdD!gwNBTG#o>lC|3x~bNfH-!xG zS@$4WhWHAI!nMB=!1DZX+2Tte_NySOJpbCnJ0PZ2ktkdHm!38O5c@d#PDN|}x$ePb z9p)Smxk#Ae*LCJ!n&&+r4h)EMCFNDpGHsW%Xn11^8Vll?YP^9}&}1d$A#Y$w8OO2N zi+!kCuVIvwSy8_W{KW+q^@~8vW-}QK2AQp=s_`aPQJ=L{wt>g!dFLYAD)T^C;!oB4 zS;sF|Qf7^!8m^q6!@7t%gzY2U^JBD-dNZsff8HEZZaca8K?x=Fg79|J!CzY>1Y-Qet^ z`$N);?qkx6?h|iYz5oWq8t|^dEc#P}I_WZ7=j^8jry;ifUqAM+1}1c{GJEsd`WF}% Vg={u)iKhSn002ovPDHLkV1o2`SGE8E From f1ff9b69b307fda028fcbcb5749ef9af358d0062 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 15 Jun 2013 15:33:47 +0200 Subject: [PATCH 131/213] Mouse grab and relative input need to be disabled when the mouse leaves the window; Disabled resolution switching / window resizing for now due to several glitches --- apps/openmw/mwgui/settingswindow.cpp | 9 ++++- apps/openmw/mwgui/windowmanagerimp.cpp | 10 +++-- apps/openmw/mwinput/inputmanagerimp.cpp | 6 +-- apps/openmw/mwrender/renderingmanager.cpp | 8 ++-- extern/sdl4ogre/sdlinputwrapper.cpp | 46 +++++++++++++++-------- extern/sdl4ogre/sdlinputwrapper.hpp | 4 ++ libs/openengine/ogre/renderer.cpp | 2 +- 7 files changed, 57 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index edce00d5d..97bccd01f 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -269,12 +269,15 @@ namespace MWGui if (index == MyGUI::ITEM_NONE) return; + /* ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog(); dialog->open("#{sNotifyMessage67}"); dialog->eventOkClicked.clear(); dialog->eventOkClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionAccept); dialog->eventCancelClicked.clear(); dialog->eventCancelClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionCancel); + */ + onResolutionAccept(); } void SettingsWindow::onResolutionAccept() @@ -287,7 +290,9 @@ namespace MWGui Settings::Manager::setInt("resolution y", "Video", resY); apply(); - mResolutionList->setIndexSelected(MyGUI::ITEM_NONE); + + MWBase::Environment::get().getWindowManager()-> + messageBox("New resolution will be applied after a restart", std::vector()); } void SettingsWindow::onResolutionCancel() @@ -356,6 +361,8 @@ namespace MWGui { Settings::Manager::setBool("fullscreen", "Video", newState); apply(); + MWBase::Environment::get().getWindowManager()-> + messageBox("Fullscreen will be applied after a restart", std::vector()); } } else if (_sender == mVSyncButton) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 17c23699f..eafa9df6e 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -876,18 +876,18 @@ namespace MWGui setUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI")); - bool changeRes = false; + //bool changeRes = false; bool windowRecreated = false; for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { - if (it->first == "Video" && ( + /*if (it->first == "Video" && ( it->second == "resolution x" || it->second == "resolution y")) { changeRes = true; - } - else if (it->first == "Video" && it->second == "vsync") + }*/ + if (it->first == "Video" && it->second == "vsync") windowRecreated = true; else if (it->first == "HUD" && it->second == "crosshair") mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD"); @@ -895,6 +895,7 @@ namespace MWGui mSubtitlesEnabled = Settings::Manager::getBool ("subtitles", "GUI"); } + /* if (changeRes) { int x = Settings::Manager::getInt("resolution x", "Video"); @@ -912,6 +913,7 @@ namespace MWGui mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); mInputBlocker->setSize(MyGUI::IntSize(x,y)); } + */ if (windowRecreated) { mGuiManager->updateWindow (mRendering->getWindow ()); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 7d99f9cc2..1c184883f 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -220,13 +220,13 @@ namespace MWInput bool was_relative = mInputManager->getMouseRelative(); bool is_relative = !mWindows.isGuiMode(); - //we let the mouse escape in the main menu - mInputManager->setGrabPointer(!main_menu); - // don't keep the pointer away from the window edge in gui mode // stop using raw mouse motions and switch to system cursor movements mInputManager->setMouseRelative(is_relative); + //we let the mouse escape in the main menu + mInputManager->setGrabPointer(!main_menu); + //we switched to non-relative mode, move our cursor to where the in-game //cursor is if( !is_relative && was_relative != is_relative ) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a60ba3060..22d47cfc0 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -719,7 +719,7 @@ Compositors* RenderingManager::getCompositors() void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) { - bool changeRes = false; + //bool changeRes = false; bool rebuild = false; // rebuild static geometry (necessary after any material changes) for (Settings::CategorySettingVector::const_iterator it=settings.begin(); it != settings.end(); ++it) @@ -733,11 +733,11 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior()) configureFog(*MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()); } - else if (it->first == "Video" && ( + /*else if (it->first == "Video" && ( it->second == "resolution x" || it->second == "resolution y" || it->second == "fullscreen")) - changeRes = true; + changeRes = true;*/ else if (it->second == "field of view" && it->first == "General") mRendering.setFov(Settings::Manager::getFloat("field of view", "General")); else if ((it->second == "texture filtering" && it->first == "General") @@ -791,6 +791,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec } } + /* if (changeRes) { unsigned int x = Settings::Manager::getInt("resolution x", "Video"); @@ -807,6 +808,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec SDL_SetWindowFullscreen(mRendering.getSDLWindow(), Settings::Manager::getBool("fullscreen", "Video") ? SDL_WINDOW_FULLSCREEN : 0); //mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); } + */ mWater->processChangedSettings(settings); diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 7cc7820f9..bd8aa75db 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -99,9 +99,6 @@ namespace SFO void InputWrapper::capture() { SDL_Event evt; - bool resize=false; - size_t size_x = 0; - size_t size_y = 0; while(SDL_PollEvent(&evt)) { switch(evt.type) @@ -125,25 +122,42 @@ namespace SFO case SDL_MOUSEBUTTONUP: mMouseListener->mouseReleased(evt.button, evt.button.button); break; - case SDL_KEYDOWN: _handleKeyPress(evt.key); break; case SDL_KEYUP: mKeyboardListener->keyReleased(evt.key); break; - case SDL_WINDOWEVENT_RESIZED: - resize = true; - size_x = evt.window.data1; - size_y = evt.window.data2; + case SDL_WINDOWEVENT: + handleWindowEvent(evt); break; case SDL_QUIT: Ogre::Root::getSingleton().queueEndRendering(); break; + default: + std::cerr << "Unhandled SDL event of type " << evt.type << std::endl; + break; } } - if (resize) - mOgreWindow->resize(size_x, size_y); + } + + void InputWrapper::handleWindowEvent(const SDL_Event& evt) + { + switch (evt.window.event) { + case SDL_WINDOWEVENT_ENTER: + mMouseInWindow = true; + break; + case SDL_WINDOWEVENT_LEAVE: + mMouseInWindow = false; + SDL_SetWindowGrab(mSDLWindow, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + break; + case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + case SDL_WINDOWEVENT_CLOSE: + break; + } } bool InputWrapper::isModifierHeld(int mod) @@ -163,25 +177,25 @@ namespace SFO /// \brief Locks the pointer to the window void InputWrapper::setGrabPointer(bool grab) { - mGrabPointer = grab; - SDL_SetWindowGrab(mSDLWindow, grab ? SDL_TRUE : SDL_FALSE); + mGrabPointer = grab && mMouseInWindow; + SDL_SetWindowGrab(mSDLWindow, grab && mMouseInWindow ? SDL_TRUE : SDL_FALSE); } /// \brief Set the mouse to relative positioning. Doesn't move the cursor /// and disables mouse acceleration. void InputWrapper::setMouseRelative(bool relative) { - if(mMouseRelative == relative) + if(mMouseRelative == relative && mMouseInWindow) return; - mMouseRelative = relative; + mMouseRelative = relative && mMouseInWindow; mWrapPointer = false; //eep, wrap the pointer manually if the input driver doesn't support //relative positioning natively - int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE); - if(relative && success != 0) + int success = SDL_SetRelativeMouseMode(relative && mMouseInWindow ? SDL_TRUE : SDL_FALSE); + if(relative && mMouseInWindow && success != 0) mWrapPointer = true; //now remove all mouse events using the old setting from the queue diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index f84ebcacc..62141d514 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -38,6 +38,8 @@ namespace SFO private: + void handleWindowEvent(const SDL_Event& evt); + bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); void _wrapMousePointer(const SDL_MouseMotionEvent &evt); MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); @@ -64,6 +66,8 @@ namespace SFO Sint32 mMouseX; Sint32 mMouseY; + bool mMouseInWindow; + SDL_Window* mSDLWindow; Ogre::RenderWindow* mOgreWindow; bool mOwnWindow; diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index e3bba8bfa..6cf87c4dd 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -241,7 +241,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& SDL_WINDOWPOS_UNDEFINED, // initial y position settings.window_x, // width, in pixels settings.window_y, // height, in pixels - SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE + SDL_WINDOW_SHOWN | (settings.fullscreen ? SDL_WINDOW_FULLSCREEN : 0) ); From 695894013154d9dd3dcf916c7f089f8b09b7c6d6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 15 Jun 2013 16:15:45 +0200 Subject: [PATCH 132/213] Ignore repeated keystrokes, except for text input events --- extern/sdl4ogre/sdlinputwrapper.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index bd8aa75db..fcd393dfa 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -123,10 +123,12 @@ namespace SFO mMouseListener->mouseReleased(evt.button, evt.button.button); break; case SDL_KEYDOWN: - _handleKeyPress(evt.key); + if (!evt.key.repeat) + _handleKeyPress(evt.key); break; case SDL_KEYUP: - mKeyboardListener->keyReleased(evt.key); + if (!evt.key.repeat) + mKeyboardListener->keyReleased(evt.key); break; case SDL_WINDOWEVENT: handleWindowEvent(evt); From 289587b1a9114a36b51897d969f326cdfd3d579e Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 15 Jun 2013 16:29:25 +0200 Subject: [PATCH 133/213] Cleanup --- apps/openmw/engine.cpp | 48 ------------------------------------------ apps/openmw/engine.hpp | 2 -- 2 files changed, 50 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index e78162c29..acc3753e4 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -77,7 +77,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) { try { - handleSDLMessages(); float frametime = std::min(evt.timeSinceLastFrame, 0.2f); mEnvironment.setFrameDuration (frametime); @@ -122,9 +121,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), tri, batch); MWBase::Environment::get().getWindowManager()->onFrame(frametime); - - //Flush any events that weren't handled this frame - SDL_FlushEvents(0x0, 0xFFFFFFFF); } catch (const std::exception& e) { @@ -134,50 +130,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) return true; } -void OMW::Engine::handleSDLMessages() -{ - /* - //Pump messages since the last frame - const int max_events = 20; - SDL_Event events[max_events]; - - SDL_PumpEvents(); - int num_events = SDL_PeepEvents(events, max_events, SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT); - - bool resize = false; - - unsigned int size_x = 0; - unsigned int size_y = 0; - - if(num_events != 0) - { - for(int i=0; i < num_events; ++i) - { - switch(events[i].window.event) - { - case SDL_WINDOWEVENT_RESIZED: - resize = true; - size_x = events[i].window.data1; - size_y = events[i].window.data2; - break; - } - } - } - - //handle window movements - if(resize) - { - mOgre->getWindow()->resize(size_x, size_y); - } - - if(SDL_PeepEvents(NULL, 1, SDL_PEEKEVENT, SDL_QUIT, SDL_QUIT) != 0) - { - //user requested a quit, break out. - mOgre->getRoot()->queueEndRendering(); - } - */ -} - OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) : mOgre (0) , mFpsLevel(0) diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index a206166a5..f80b67a35 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -105,8 +105,6 @@ namespace OMW void executeLocalScripts(); - void handleSDLMessages(); - virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); virtual bool frameStarted (const Ogre::FrameEvent& evt); From 5252ffa104ae7b5f3bcd198a83c12425dcd91429 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 15 Jun 2013 16:53:54 +0200 Subject: [PATCH 134/213] More cleanup --- apps/openmw/mwinput/inputmanagerimp.cpp | 1 - apps/openmw/mwrender/renderingmanager.cpp | 2 - extern/sdl4ogre/sdlinputwrapper.cpp | 55 +---------------------- extern/sdl4ogre/sdlinputwrapper.hpp | 2 - 4 files changed, 1 insertion(+), 59 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 1c184883f..e3fc0ba2a 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 22d47cfc0..9de183978 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -16,8 +16,6 @@ #include #include -#include "SDL2/SDL.h" - #include #include diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index fcd393dfa..3f1b8577f 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -30,6 +30,7 @@ namespace SFO { _setupOISKeys(); + // FIXME: text input should only be enabled when a text input widget currently has focus SDL_StartTextInput(); } @@ -42,60 +43,6 @@ namespace SFO SDL_StopTextInput(); } - /* - void InputWrapper::initFromRenderWindow(Ogre::RenderWindow *win) - { - assert(mSDLWindow == NULL); - - mOwnWindow = true; - - //get the HWND from ogre's renderwindow - size_t windowHnd; - win->getCustomAttribute("WINDOW", &windowHnd); - - //wrap our own event handler around ogre's - mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); - - assert(mSDLWindow != NULL); - - //without this SDL will take ownership of the window and iconify it when - //we alt-tab away. - //SDL_SetWindowFullscreen(mSDLWindow, 0); - -#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX - //linux-specific event-handling fixups - //see http://bugzilla.libsdl.org/show_bug.cgi?id=730 - SDL_SysWMinfo wm_info; - SDL_VERSION(&wm_info.version); - - if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info)) - { - Display* display = wm_info.info.x11.display; - Window w = wm_info.info.x11.window; - - // Set the input hints so we get keyboard input - XWMHints *wmhints = XAllocWMHints(); - if (wmhints) { - wmhints->input = True; - wmhints->flags = InputHint; - XSetWMHints(display, w, wmhints); - XFree(wmhints); - } - - //make sure to subscribe to XLib's events - XSelectInput(display, w, - (FocusChangeMask | EnterWindowMask | LeaveWindowMask | - ExposureMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | KeyPressMask | KeyReleaseMask | - PropertyChangeMask | StructureNotifyMask | - KeymapStateMask)); - - XFlush(display); - } -#endif - } - */ - void InputWrapper::capture() { SDL_Event evt; diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index 62141d514..cb9804d54 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -19,8 +19,6 @@ namespace SFO InputWrapper(SDL_Window *window, Ogre::RenderWindow* ogreWindow); ~InputWrapper(); - //void initFromRenderWindow(Ogre::RenderWindow* win); - void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; } void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; } void setWindowEventCallback(WindowListener* listen) { mWindowListener = listen; } From 4c0086b54c9811dfc94cb0351321ec588143d952 Mon Sep 17 00:00:00 2001 From: vorenon Date: Sun, 16 Jun 2013 01:09:03 +0200 Subject: [PATCH 135/213] Workaround for bug #820 --- apps/openmw/mwgui/dialogue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 64c61abc0..647ec0f8d 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -471,7 +471,7 @@ namespace MWGui const MyGUI::Colour linkHot (223/255.f, 201/255.f, 159/255.f); const MyGUI::Colour linkNormal (150/255.f, 50/255.f, 30/255.f); const MyGUI::Colour linkActive (243/255.f, 237/255.f, 221/255.f); - for (std::map::iterator it = mChoices.begin(); it != mChoices.end(); ++it) + for (std::map::reverse_iterator it = mChoices.rbegin(); it != mChoices.rend(); ++it) { Choice* link = new Choice(it->second); mLinks.push_back(link); From 9ac4a9c5eb02b63821ebff240309a4b42e2d2045 Mon Sep 17 00:00:00 2001 From: vorenon Date: Sun, 16 Jun 2013 04:56:27 +0200 Subject: [PATCH 136/213] Don't start OpenMW if no master file is selected. This fixes bug #813 --- apps/openmw/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 1fa461c2f..f18d63d3f 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -217,8 +217,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat StringsVector master = variables["master"].as(); if (master.empty()) { - std::cout << "No master file given. Assuming Morrowind.esm" << std::endl; - master.push_back("Morrowind"); + std::cout << "No master file given. Aborting...\n"; + std::exit(1); } StringsVector plugin = variables["plugin"].as(); From 50e5aa897648246c253b59313a288c294faf9f12 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 16 Jun 2013 16:25:13 +0400 Subject: [PATCH 137/213] Custom rendering loop on OS X again. Prevents default Ogre message pump from stealing input events. --- libs/openengine/ogre/renderer.cpp | 34 ++++++++++++++++++++++++++++++- libs/openengine/ogre/renderer.hpp | 21 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index e3bba8bfa..72a02142f 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -23,13 +23,29 @@ #include #include -#ifdef __MACOSX__ +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE #include "osx_utils.h" #endif using namespace Ogre; using namespace OEngine::Render; + +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE + +CustomRoot::CustomRoot(const Ogre::String& pluginFileName, + const Ogre::String& configFileName, + const Ogre::String& logFileName) +: Ogre::Root(pluginFileName, configFileName, logFileName) +{} + +bool CustomRoot::isQueuedEnd() const +{ + return mQueuedEnd; +} + +#endif + void OgreRenderer::cleanup() { delete mFader; @@ -52,7 +68,19 @@ void OgreRenderer::cleanup() void OgreRenderer::start() { +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE + // we need this custom main loop because otherwise Ogre's Carbon message pump will + // steal input events even from our Cocoa window + // There's no way to disable Ogre's message pump other that comment pump code in Ogre's source + do { + if (!mRoot->renderOneFrame()) { + break; + } + + } while (!mRoot->isQueuedEnd()); +#else mRoot->startRendering(); +#endif } void OgreRenderer::loadPlugins() @@ -145,7 +173,11 @@ void OgreRenderer::configure(const std::string &logPath, // Disable logging log->setDebugOutputEnabled(false); +#if defined(__APPLE__) && !defined(__LP64__) + mRoot = new CustomRoot("", "", ""); +#else mRoot = new Root("", "", ""); +#endif #if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX) loadPlugins(); diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index 0cd0e74e8..a451490fb 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -27,12 +27,18 @@ #include "OgreTexture.h" #include +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE +#include +#endif + struct SDL_Window; struct SDL_Surface; namespace Ogre { +#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE class Root; +#endif class RenderWindow; class SceneManager; class Camera; @@ -54,11 +60,26 @@ namespace OEngine std::string icon; }; +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE + class CustomRoot : public Ogre::Root { + public: + bool isQueuedEnd() const; + + CustomRoot(const Ogre::String& pluginFileName = "plugins.cfg", + const Ogre::String& configFileName = "ogre.cfg", + const Ogre::String& logFileName = "Ogre.log"); + }; +#endif + class Fader; class OgreRenderer { +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE + CustomRoot *mRoot; +#else Ogre::Root *mRoot; +#endif Ogre::RenderWindow *mWindow; SDL_Window *mSDLWindow; SDL_Surface *mWindowIconSurface; From 88acebf808493db19a845a5d51969778dc5b9dde Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Jun 2013 17:10:30 +0200 Subject: [PATCH 138/213] Fix an uninitalized member, and also make sure the mouse is captured when OpenMW starts --- extern/sdl4ogre/sdlinputwrapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 3f1b8577f..e02d885b5 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -26,7 +26,8 @@ namespace SFO mWrapPointer(false), mMouseZ(0), mMouseY(0), - mMouseX(0) + mMouseX(0), + mMouseInWindow(true) { _setupOISKeys(); From 03682184c67c7b72a7a2f9deb21c3572b80b83fa Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Jun 2013 18:06:55 +0200 Subject: [PATCH 139/213] Enable SDL_TEXTINPUT events only when a text input widget currently has key focus --- apps/openmw/mwbase/windowmanager.hpp | 2 ++ apps/openmw/mwgui/class.cpp | 4 ++-- apps/openmw/mwgui/console.cpp | 9 +++------ apps/openmw/mwgui/countdialog.cpp | 5 ++++- apps/openmw/mwgui/textinput.cpp | 8 ++++---- apps/openmw/mwgui/windowmanagerimp.cpp | 21 ++++++++++++++++++++- apps/openmw/mwgui/windowmanagerimp.hpp | 3 +++ extern/sdl4ogre/sdlinputwrapper.cpp | 5 ----- 8 files changed, 38 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index c36278b6d..36d4ab8bb 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -264,6 +264,8 @@ namespace MWBase virtual void changePointer (const std::string& name) = 0; virtual const Translation::Storage& getTranslationDataStorage() const = 0; + + virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0; }; } diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index ab8103868..2f00918b0 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -407,7 +407,7 @@ namespace MWGui getWidget(mEditName, "EditName"); // Make sure the edit box has focus - MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mEditName); MyGUI::Button* descriptionButton; getWidget(descriptionButton, "DescriptionButton"); @@ -866,7 +866,7 @@ namespace MWGui okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", "")); // Make sure the edit box has focus - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } DescriptionDialog::~DescriptionDialog() diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index b69d2d6af..f438d5e09 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -5,6 +5,7 @@ #include "../mwscript/extensions.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" namespace MWGui { @@ -131,16 +132,12 @@ namespace MWGui // Give keyboard focus to the combo box whenever the console is // turned on - MyGUI::InputManager::getInstance().setKeyFocusWidget(command); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(command); } void Console::disable() { setVisible(false); - - // Remove keyboard focus from the console input whenever the - // console is turned off - MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL); } void Console::setFont(const std::string &fntName) @@ -415,7 +412,7 @@ namespace MWGui setTitle("#{sConsoleTitle}"); mPtr = MWWorld::Ptr(); } - MyGUI::InputManager::getInstance().setKeyFocusWidget(command); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(command); } void Console::onReferenceUnavailable() diff --git a/apps/openmw/mwgui/countdialog.cpp b/apps/openmw/mwgui/countdialog.cpp index 354de561d..c429b0ccf 100644 --- a/apps/openmw/mwgui/countdialog.cpp +++ b/apps/openmw/mwgui/countdialog.cpp @@ -2,6 +2,9 @@ #include +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + namespace MWGui { CountDialog::CountDialog() : @@ -40,7 +43,7 @@ namespace MWGui mMainWidget->getHeight()); // by default, the text edit field has the focus of the keyboard - MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit); mSlider->setScrollPosition(maxCount-1); mItemEdit->setCaption(boost::lexical_cast(maxCount)); diff --git a/apps/openmw/mwgui/textinput.cpp b/apps/openmw/mwgui/textinput.cpp index d4f8a2533..954bc41ab 100644 --- a/apps/openmw/mwgui/textinput.cpp +++ b/apps/openmw/mwgui/textinput.cpp @@ -20,7 +20,7 @@ namespace MWGui okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); // Make sure the edit box has focus - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } void TextInputDialog::setNextButtonShow(bool shown) @@ -43,7 +43,7 @@ namespace MWGui { WindowModal::open(); // Make sure the edit box has focus - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } // widget controls @@ -53,7 +53,7 @@ namespace MWGui if (mTextEdit->getCaption() == "") { MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}"); - MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget (mTextEdit); } else eventDone(this); @@ -64,7 +64,7 @@ namespace MWGui if (mTextEdit->getCaption() == "") { MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}"); - MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget (mTextEdit); } else eventDone(this); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index eafa9df6e..c57fd7550 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -225,6 +225,8 @@ namespace MWGui MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange); + MyGUI::InputManager::getInstance().eventChangeKeyFocus += MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged); + setUseHardwareCursors(mUseHardwareCursors); onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer()); mCursorManager->cursorVisibilityChange(false); @@ -360,7 +362,7 @@ namespace MWGui mToolTips->enterGuiMode(); if (gameMode) - MyGUI::InputManager::getInstance ().setKeyFocusWidget (NULL); + setKeyFocusWidget (NULL); setMinimapVisibility((mAllowed & GW_Map) && !mMap->pinned()); setWeaponVisibility((mAllowed & GW_Inventory) && !mInventoryWindow->pinned()); @@ -1299,4 +1301,21 @@ namespace MWGui mInventoryWindow->updatePlayer(); } + void WindowManager::setKeyFocusWidget(MyGUI::Widget *widget) + { + if (widget == NULL) + MyGUI::InputManager::getInstance().resetKeyFocusWidget(); + else + MyGUI::InputManager::getInstance().setKeyFocusWidget(widget); + onKeyFocusChanged(widget); + } + + void WindowManager::onKeyFocusChanged(MyGUI::Widget *widget) + { + if (widget && widget->castType(false)) + SDL_StartTextInput(); + else + SDL_StopTextInput(); + } + } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 31b829cda..42f2f4dc2 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -98,6 +98,8 @@ namespace MWGui */ virtual void update(); + virtual void setKeyFocusWidget (MyGUI::Widget* widget); + virtual void setNewGame(bool newgame); virtual void pushGuiMode(GuiMode mode); @@ -353,6 +355,7 @@ namespace MWGui void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result); void onCursorChange(const std::string& name); + void onKeyFocusChanged(MyGUI::Widget* widget); }; } diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index e02d885b5..a6d464027 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -30,9 +30,6 @@ namespace SFO mMouseInWindow(true) { _setupOISKeys(); - - // FIXME: text input should only be enabled when a text input widget currently has focus - SDL_StartTextInput(); } InputWrapper::~InputWrapper() @@ -40,8 +37,6 @@ namespace SFO if(mSDLWindow != NULL && mOwnWindow) SDL_DestroyWindow(mSDLWindow); mSDLWindow = NULL; - - SDL_StopTextInput(); } void InputWrapper::capture() From ed6098388f5c55209372780758e52ad423b594cc Mon Sep 17 00:00:00 2001 From: vorenon Date: Sun, 16 Jun 2013 18:13:14 +0200 Subject: [PATCH 140/213] return false instead of std::exit --- apps/openmw/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index f18d63d3f..7f803f3a7 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -218,7 +218,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat if (master.empty()) { std::cout << "No master file given. Aborting...\n"; - std::exit(1); + return false; } StringsVector plugin = variables["plugin"].as(); From b16c92c2f53f0e9b3ffc510209090c8717589deb Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Jun 2013 19:43:59 +0200 Subject: [PATCH 141/213] Better handle SDL_TEXTINPUT events --- apps/openmw/mwgui/loadingscreen.cpp | 3 +- apps/openmw/mwinput/inputmanagerimp.cpp | 71 ++++++++++++++++++++++- apps/openmw/mwinput/inputmanagerimp.hpp | 1 + extern/sdl4ogre/events.h | 1 + extern/sdl4ogre/sdlinputwrapper.cpp | 75 ++----------------------- extern/sdl4ogre/sdlinputwrapper.hpp | 2 - 6 files changed, 77 insertions(+), 76 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 018f51feb..d4b06b2ab 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -10,6 +10,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/inputmanager.hpp" namespace MWGui { @@ -126,7 +127,7 @@ namespace MWGui // always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before // (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow) - //MWBase::Environment::get().getInputManager()->update(0, true); + MWBase::Environment::get().getInputManager()->update(0, true); Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0)); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index f53508f86..2fd8b4085 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -23,6 +23,65 @@ using namespace ICS; +namespace +{ + std::vector utf8ToUnicode(const std::string& utf8) + { + std::vector unicode; + size_t i = 0; + while (i < utf8.size()) + { + unsigned long uni; + size_t todo; + unsigned char ch = utf8[i++]; + if (ch <= 0x7F) + { + uni = ch; + todo = 0; + } + else if (ch <= 0xBF) + { + throw std::logic_error("not a UTF-8 string"); + } + else if (ch <= 0xDF) + { + uni = ch&0x1F; + todo = 1; + } + else if (ch <= 0xEF) + { + uni = ch&0x0F; + todo = 2; + } + else if (ch <= 0xF7) + { + uni = ch&0x07; + todo = 3; + } + else + { + throw std::logic_error("not a UTF-8 string"); + } + for (size_t j = 0; j < todo; ++j) + { + if (i == utf8.size()) + throw std::logic_error("not a UTF-8 string"); + unsigned char ch = utf8[i++]; + if (ch < 0x80 || ch > 0xBF) + throw std::logic_error("not a UTF-8 string"); + uni <<= 6; + uni += ch & 0x3F; + } + if (uni >= 0xD800 && uni <= 0xDFFF) + throw std::logic_error("not a UTF-8 string"); + if (uni > 0x10FFFF) + throw std::logic_error("not a UTF-8 string"); + unicode.push_back(uni); + } + return unicode; + } +} + namespace MWInput { InputManager::InputManager(OEngine::Render::OgreRenderer &ogre, @@ -422,11 +481,19 @@ namespace MWInput OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); - MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), text); - + if (kc != OIS::KC_UNASSIGNED) + MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0); return true; } + void InputManager::textInput(const SDL_TextInputEvent &arg) + { + const char* text = &arg.text[0]; + std::vector unicode = utf8ToUnicode(std::string(text)); + for (std::vector::iterator it = unicode.begin(); it != unicode.end(); ++it) + MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it); + } + bool InputManager::keyReleased(const SDL_KeyboardEvent &arg ) { mInputBinder->keyReleased (arg); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 57c367bde..788f116ac 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -88,6 +88,7 @@ namespace MWInput public: virtual bool keyPressed(const SDL_KeyboardEvent &arg ); virtual bool keyReleased( const SDL_KeyboardEvent &arg ); + virtual void textInput (const SDL_TextInputEvent &arg); virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ); virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ); diff --git a/extern/sdl4ogre/events.h b/extern/sdl4ogre/events.h index 5a0146635..13f8b3101 100644 --- a/extern/sdl4ogre/events.h +++ b/extern/sdl4ogre/events.h @@ -35,6 +35,7 @@ class KeyListener { public: virtual ~KeyListener() {} + virtual void textInput (const SDL_TextInputEvent& arg) {} virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0; virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0; }; diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index a6d464027..5c1df52c6 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -67,12 +67,15 @@ namespace SFO break; case SDL_KEYDOWN: if (!evt.key.repeat) - _handleKeyPress(evt.key); + mKeyboardListener->keyPressed(evt.key); break; case SDL_KEYUP: if (!evt.key.repeat) mKeyboardListener->keyReleased(evt.key); break; + case SDL_TEXTINPUT: + mKeyboardListener->textInput(evt.text); + break; case SDL_WINDOWEVENT: handleWindowEvent(evt); break; @@ -220,74 +223,6 @@ namespace SFO return pack_evt; } - void InputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt) - { - //SDL keyboard events are followed by the actual text those keys would generate - //to account for languages that require multiple keystrokes to produce a key. - //Look for an event immediately following ours, assuming each key produces exactly - //one character or none at all. - - //TODO: Check if this works properly for multibyte symbols - //do we have to worry about endian-ness? - //for that matter, check if we even need to do any of this. - - SDL_Event text_evts[1]; - if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0) - { - if(strlen(text_evts[0].text.text) != 0) - { - const unsigned char* symbol = reinterpret_cast(&(text_evts[0].text.text[0])); - evt.keysym.unicode = _UTF8ToUTF32(symbol); - } - } - - mKeyboardListener->keyPressed(evt); - } - - //Lifted from OIS' LinuxKeyboard.cpp - Uint32 InputWrapper::_UTF8ToUTF32(const unsigned char *buf) - { - unsigned char FirstChar = buf[0]; - - //it's an ascii char, bail out early. - if(FirstChar < 128) - return FirstChar; - - Uint32 val = 0; - Sint32 len = 0; - - if((FirstChar & 0xE0) == 0xC0) //2 Chars - { - len = 2; - val = FirstChar & 0x1F; - } - else if((FirstChar & 0xF0) == 0xE0) //3 Chars - { - len = 3; - val = FirstChar & 0x0F; - } - else if((FirstChar & 0xF8) == 0xF0) //4 Chars - { - len = 4; - val = FirstChar & 0x07; - } - else if((FirstChar & 0xFC) == 0xF8) //5 Chars - { - len = 5; - val = FirstChar & 0x03; - } - else // if((FirstChar & 0xFE) == 0xFC) //6 Chars - { - len = 6; - val = FirstChar & 0x01; - } - - for(int i = 1; i < len; i++) - val = (val << 6) | (buf[i] & 0x3F); - - return val; - } - OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code) { OIS::KeyCode kc = OIS::KC_UNASSIGNED; @@ -296,8 +231,6 @@ namespace SFO if(ois_equiv != mKeyMap.end()) kc = ois_equiv->second; - else - std::cerr << "Couldn't find OIS key for " << code << std::endl; return kc; } diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index cb9804d54..08b329925 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -42,8 +42,6 @@ namespace SFO void _wrapMousePointer(const SDL_MouseMotionEvent &evt); MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); - void _handleKeyPress(SDL_KeyboardEvent& evt); - Uint32 _UTF8ToUTF32(const unsigned char *buf); void _setupOISKeys(); SFO::MouseListener* mMouseListener; From 76a2abcbe32fe667cc7d62be1a1db517618d814d Mon Sep 17 00:00:00 2001 From: vorenon Date: Sun, 16 Jun 2013 19:46:55 +0200 Subject: [PATCH 142/213] added missing line break in front of multiple choice questions --- apps/openmw/mwgui/dialogue.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 647ec0f8d..8a57234b8 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -467,6 +467,7 @@ namespace MWGui BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::White); + typesetter->sectionBreak(9); // choices const MyGUI::Colour linkHot (223/255.f, 201/255.f, 159/255.f); const MyGUI::Colour linkNormal (150/255.f, 50/255.f, 30/255.f); From de2868c0a35c963f4f7552d24c90617c68ece72f Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 16 Jun 2013 21:47:26 +0400 Subject: [PATCH 143/213] Fixed 64-bit OS X build --- libs/openengine/ogre/renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index bc2e38fa5..5807a9482 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -173,7 +173,7 @@ void OgreRenderer::configure(const std::string &logPath, // Disable logging log->setDebugOutputEnabled(false); -#if defined(__APPLE__) && !defined(__LP64__) +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE mRoot = new CustomRoot("", "", ""); #else mRoot = new Root("", "", ""); From 4fd7891d2cf57e7531c07da0e288c6eed197f186 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Jun 2013 20:26:27 +0200 Subject: [PATCH 144/213] Fix a message box issue --- apps/openmw/mwgui/tooltips.cpp | 15 +++------------ apps/openmw/mwgui/tooltips.hpp | 5 ----- apps/openmw/mwgui/windowmanagerimp.cpp | 5 ----- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- 4 files changed, 4 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index e73ed6b5e..9cbb3cced 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -18,7 +18,6 @@ namespace MWGui ToolTips::ToolTips() : Layout("openmw_tooltips.layout") - , mGameMode(true) , mFullHelp(false) , mEnabled(true) , mFocusToolTipX(0.0) @@ -73,7 +72,9 @@ namespace MWGui return; } - if (!mGameMode) + bool gameMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); + + if (gameMode) { const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition(); @@ -297,16 +298,6 @@ namespace MWGui } } - void ToolTips::enterGameMode() - { - mGameMode = true; - } - - void ToolTips::enterGuiMode() - { - mGameMode = false; - } - void ToolTips::setFocusObject(const MWWorld::Ptr& focus) { mFocusObject = focus; diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index f8f256167..a8524a4ca 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -43,9 +43,6 @@ namespace MWGui void onFrame(float frameDuration); - void enterGameMode(); - void enterGuiMode(); - void setEnabled(bool enabled); void toggleFullHelp(); ///< show extra info in item tooltips (owner, script) @@ -104,8 +101,6 @@ namespace MWGui int mLastMouseX; int mLastMouseY; - bool mGameMode; - bool mEnabled; bool mFullHelp; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index c57fd7550..5ca82bc8a 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -356,11 +356,6 @@ namespace MWGui mInputBlocker->setVisible (gameMode); setCursorVisible(!gameMode); - if (gameMode) - mToolTips->enterGameMode(); - else - mToolTips->enterGuiMode(); - if (gameMode) setKeyFocusWidget (NULL); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 2fd8b4085..724caf874 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -408,6 +408,7 @@ namespace MWInput mMouseLookEnabled = !guiMode; if (guiMode) mWindows.showCrosshair(false); + mWindows.setCursorVisible(guiMode); // if not in gui mode, the camera decides whether to show crosshair or not. } @@ -470,7 +471,6 @@ namespace MWInput bool InputManager::keyPressed( const SDL_KeyboardEvent &arg ) { mInputBinder->keyPressed (arg); - unsigned int text = arg.keysym.unicode; if(arg.keysym.sym == SDLK_RETURN && MWBase::Environment::get().getWindowManager()->isGuiMode()) From b16bc694798d3218461b1ba9e91ee6fc7bb62dd2 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Jun 2013 20:39:40 +0200 Subject: [PATCH 145/213] Removed the no longer needed --debug switch --- apps/openmw/engine.cpp | 7 ----- apps/openmw/engine.hpp | 5 ---- apps/openmw/main.cpp | 4 --- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 37 +++++++++---------------- apps/openmw/mwinput/inputmanagerimp.hpp | 1 - extern/sdl4ogre/sdlcursormanager.cpp | 11 ++------ extern/sdl4ogre/sdlcursormanager.hpp | 4 +-- 8 files changed, 18 insertions(+), 53 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index acc3753e4..6c7247845 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -133,7 +133,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) : mOgre (0) , mFpsLevel(0) - , mDebug (false) , mVerboseScripts (false) , mNewGame (false) , mUseSound (true) @@ -283,11 +282,6 @@ void OMW::Engine::addPlugin (const std::string& plugin) } } -void OMW::Engine::setDebugMode(bool debugMode) -{ - mDebug = debugMode; -} - void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity) { mVerboseScripts = scriptsVerbosity; @@ -331,7 +325,6 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings) nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); settings.setBool("hardware cursors", "GUI", true); - settings.setBool("debug", "Engine", mDebug); return settingspath; } diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index f80b67a35..665b0094c 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -71,7 +71,6 @@ namespace OMW std::vector mMaster; std::vector mPlugins; int mFpsLevel; - bool mDebug; bool mVerboseScripts; bool mNewGame; bool mUseSound; @@ -147,10 +146,6 @@ namespace OMW /// Enable fps counter void showFPS(int level); - /// Enable debug mode: - /// - non-exclusive input - void setDebugMode(bool debugMode); - /// Enable or disable verbose script output void setScriptsVerbosity(bool scriptsVerbosity); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 1fa461c2f..4e40211ba 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -118,9 +118,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("anim-verbose", bpo::value()->implicit_value(true) ->default_value(false), "output animation indices files") - ("debug", bpo::value()->implicit_value(true) - ->default_value(false), "debug mode") - ("nosound", bpo::value()->implicit_value(true) ->default_value(false), "disable all sounds") @@ -243,7 +240,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat engine.setNewGame(variables["new-game"].as()); // other settings - engine.setDebugMode(variables["debug"].as()); engine.setSoundUsage(!variables["nosound"].as()); engine.setScriptsVerbosity(variables["script-verbose"].as()); engine.setCompileAll(variables["script-all"].as()); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5ca82bc8a..38efbbff0 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -221,7 +221,7 @@ namespace MWGui unsetSelectedWeapon(); //set up the hardware cursor manager - mCursorManager = new SFO::SDLCursorManager(Settings::Manager::getBool("debug", "Engine")); + mCursorManager = new SFO::SDLCursorManager(); MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 724caf874..f19f63458 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -99,7 +99,6 @@ namespace MWInput , mMouseWheel(0) , mDragDrop(false) , mGuiCursorEnabled(false) - , mDebug(Settings::Manager::getBool("debug", "Engine")) , mUserFile(userFile) , mUserFileExists(userFileExists) , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) @@ -272,26 +271,23 @@ namespace MWInput // event callbacks (which may crash) mWindows.update(); - if(!mDebug) - { - bool main_menu = mWindows.containsMode(MWGui::GM_MainMenu); + bool main_menu = mWindows.containsMode(MWGui::GM_MainMenu); - bool was_relative = mInputManager->getMouseRelative(); - bool is_relative = !mWindows.isGuiMode(); + bool was_relative = mInputManager->getMouseRelative(); + bool is_relative = !mWindows.isGuiMode(); - // don't keep the pointer away from the window edge in gui mode - // stop using raw mouse motions and switch to system cursor movements - mInputManager->setMouseRelative(is_relative); + // don't keep the pointer away from the window edge in gui mode + // stop using raw mouse motions and switch to system cursor movements + mInputManager->setMouseRelative(is_relative); - //we let the mouse escape in the main menu - mInputManager->setGrabPointer(!main_menu); + //we let the mouse escape in the main menu + mInputManager->setGrabPointer(!main_menu); - //we switched to non-relative mode, move our cursor to where the in-game - //cursor is - if( !is_relative && was_relative != is_relative ) - { - mInputManager->warpMouse(mMouseX, mMouseY); - } + //we switched to non-relative mode, move our cursor to where the in-game + //cursor is + if( !is_relative && was_relative != is_relative ) + { + mInputManager->warpMouse(mMouseX, mMouseY); } // Disable movement in Gui mode @@ -597,19 +593,12 @@ namespace MWInput bool InputManager::windowFocusChange(bool have_focus) { - if(!mDebug) - { - - } return true; } bool InputManager::windowVisibilityChange(bool visible) { - if(!mDebug) - { //TODO: Pause game? - } return true; } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 788f116ac..f463de811 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -147,7 +147,6 @@ namespace MWInput bool mMouseLookEnabled; bool mGuiCursorEnabled; - bool mDebug; float mOverencumberedMessageDelay; diff --git a/extern/sdl4ogre/sdlcursormanager.cpp b/extern/sdl4ogre/sdlcursormanager.cpp index d817ce9c4..d14a9ffa0 100644 --- a/extern/sdl4ogre/sdlcursormanager.cpp +++ b/extern/sdl4ogre/sdlcursormanager.cpp @@ -8,8 +8,7 @@ namespace SFO { - SDLCursorManager::SDLCursorManager(bool debug) : - mDebug(debug), + SDLCursorManager::SDLCursorManager() : mEnabled(false), mCursorVisible(false), mInitialized(false) @@ -45,8 +44,7 @@ namespace SFO //turn off hardware cursors else { - if(!mDebug) - SDL_ShowCursor(SDL_FALSE); + SDL_ShowCursor(SDL_FALSE); } } @@ -72,7 +70,7 @@ namespace SFO void SDLCursorManager::_setGUICursor(const std::string &name) { - if(mEnabled && (mDebug || mCursorVisible)) + if(mEnabled && mCursorVisible) { SDL_SetCursor(mCursorMap.find(name)->second); _setCursorVisible(mCursorVisible); @@ -84,9 +82,6 @@ namespace SFO if(!mEnabled) return; - if(mDebug) - visible = true; - SDL_ShowCursor(visible ? SDL_TRUE : SDL_FALSE); } diff --git a/extern/sdl4ogre/sdlcursormanager.hpp b/extern/sdl4ogre/sdlcursormanager.hpp index 2cfb73a91..3dae42f42 100644 --- a/extern/sdl4ogre/sdlcursormanager.hpp +++ b/extern/sdl4ogre/sdlcursormanager.hpp @@ -12,7 +12,7 @@ namespace SFO public CursorManager { public: - SDLCursorManager(bool debug=false); + SDLCursorManager(); virtual ~SDLCursorManager(); virtual void setEnabled(bool enabled); @@ -36,8 +36,6 @@ namespace SFO bool mEnabled; bool mInitialized; bool mCursorVisible; - bool mDebug; - }; } From 43455129d0211eac758532047067e6c50ee2825a Mon Sep 17 00:00:00 2001 From: darkf Date: Mon, 17 Jun 2013 08:58:48 +0000 Subject: [PATCH 146/213] launcher: Instead of killing config writing due to no master files being selected, instead display a warning when Play is pressed. --- apps/launcher/maindialog.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index a5fe8dcae..1fa6a6480 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -531,17 +531,6 @@ bool MainDialog::writeSettings() } } - if(!mGameSettings.hasMaster()) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
You do not have any master files selected.

\ - Please select one and try again.
")); - msgBox.exec(); - return false; - } - // Game settings QFile file(userPath + QString("openmw.cfg")); @@ -624,6 +613,17 @@ void MainDialog::play() return; } + if(!mGameSettings.hasMaster()) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("No master file selected")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
You do not have any master files selected.

\ + OpenMW will not start without a master file selected.
")); + msgBox.exec(); + return; + } + // Launch the game detached startProgram(QString("openmw"), true); qApp->quit(); From 452df939738f1f849a28b6096f4af87a0765180e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 17 Jun 2013 15:31:35 +0200 Subject: [PATCH 147/213] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 630f6ff39..411625d09 100644 --- a/credits.txt +++ b/credits.txt @@ -21,6 +21,7 @@ BrotherBrick Chris Robinson (KittyCat) Cory F. Cohen (cfcohen) Cris Mihalache (Mirceam) +darkf Douglas Diniz (Dgdiniz) Douglas Mencken (dougmencken) Edmondo Tommasina (edmondo) From 9313b2b3feda626df52b0ba52db60fc9d8a3868f Mon Sep 17 00:00:00 2001 From: Thoronador Date: Mon, 17 Jun 2013 03:11:26 +0200 Subject: [PATCH 148/213] better const correctness for MwIniImporter --- apps/mwiniimporter/importer.cpp | 54 ++++++++++++++++----------------- apps/mwiniimporter/importer.hpp | 23 +++++++------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index fc9ce417c..e5d4dd2ca 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -635,17 +635,17 @@ MwIniImporter::MwIniImporter() } } -void MwIniImporter::setVerbose(bool verbose) { +void MwIniImporter::setVerbose(const bool verbose) { mVerbose = verbose; } -std::string MwIniImporter::numberToString(int n) { +std::string MwIniImporter::numberToString(const int n) { std::stringstream str; str << n; return str.str(); } -MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) { +MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filename) const { std::cout << "load ini file: " << filename << std::endl; std::string section(""); @@ -701,7 +701,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) { return map; } -MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) { +MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filename) { std::cout << "load cfg file: " << filename << std::endl; MwIniImporter::multistrmap map; @@ -738,12 +738,11 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) { return map; } -void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) { - multistrmap::iterator cfgIt; - multistrmap::iterator iniIt; - for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) { +void MwIniImporter::merge(multistrmap &cfg, const multistrmap &ini) const { + multistrmap::const_iterator iniIt; + for(strmap::const_iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) { if((iniIt = ini.find(it->second)) != ini.end()) { - for(std::vector::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) { + for(std::vector::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) { cfg.erase(it->first); insertMultistrmap(cfg, it->first, *vc); } @@ -751,14 +750,13 @@ void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) { } } -void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) { +void MwIniImporter::mergeFallback(multistrmap &cfg, const multistrmap &ini) const { cfg.erase("fallback"); - multistrmap::iterator cfgIt; - multistrmap::iterator iniIt; - for(std::vector::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) { + multistrmap::const_iterator iniIt; + for(std::vector::const_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) { + for(std::vector::const_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(), ':', '_' ); @@ -769,21 +767,21 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) { } } -void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) { - multistrmap::iterator it = cfg.find(key); +void MwIniImporter::insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value) { + const multistrmap::const_iterator it = cfg.find(key); if(it == cfg.end()) { cfg.insert(std::make_pair (key, std::vector() )); } cfg[key].push_back(value); } -void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) { +void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) const { std::vector archives; std::string baseArchive("Archives:Archive "); std::string archive; // Search archives listed in ini file - multistrmap::iterator it = ini.begin(); + multistrmap::const_iterator it = ini.begin(); for(int i=0; it != ini.end(); i++) { archive = baseArchive; archive.append(this->numberToString(i)); @@ -793,7 +791,7 @@ void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) { break; } - for(std::vector::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { + for(std::vector::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { archives.push_back(*entry); } } @@ -805,18 +803,18 @@ void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) { // does not appears in the ini file cfg["fallback-archive"].push_back("Morrowind.bsa"); - for(std::vector::iterator it=archives.begin(); it!=archives.end(); ++it) { + for(std::vector::const_iterator it=archives.begin(); it!=archives.end(); ++it) { cfg["fallback-archive"].push_back(*it); } } -void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { +void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) const { std::vector esmFiles; std::vector espFiles; std::string baseGameFile("Game Files:GameFile"); std::string gameFile(""); - multistrmap::iterator it = ini.begin(); + multistrmap::const_iterator it = ini.begin(); for(int i=0; it != ini.end(); i++) { gameFile = baseGameFile; gameFile.append(this->numberToString(i)); @@ -826,7 +824,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { break; } - for(std::vector::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { + for(std::vector::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { std::string filetype(entry->substr(entry->length()-3)); Misc::StringUtils::toLower(filetype); @@ -844,22 +842,22 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { cfg.erase("master"); cfg.insert( std::make_pair > ("master", std::vector() ) ); - for(std::vector::iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) { + for(std::vector::const_iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) { cfg["master"].push_back(*it); } cfg.erase("plugin"); cfg.insert( std::make_pair > ("plugin", std::vector() ) ); - for(std::vector::iterator it=espFiles.begin(); it!=espFiles.end(); ++it) { + for(std::vector::const_iterator it=espFiles.begin(); it!=espFiles.end(); ++it) { cfg["plugin"].push_back(*it); } } -void MwIniImporter::writeToFile(boost::iostreams::stream &out, multistrmap &cfg) { +void MwIniImporter::writeToFile(boost::iostreams::stream &out, const multistrmap &cfg) { - for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); ++it) { - for(std::vector::iterator entry=it->second.begin(); entry != it->second.end(); ++entry) { + for(multistrmap::const_iterator it=cfg.begin(); it != cfg.end(); ++it) { + for(std::vector::const_iterator entry=it->second.begin(); entry != it->second.end(); ++entry) { out << (it->first) << "=" << (*entry) << std::endl; } } diff --git a/apps/mwiniimporter/importer.hpp b/apps/mwiniimporter/importer.hpp index 6b99810bc..362b8c29c 100644 --- a/apps/mwiniimporter/importer.hpp +++ b/apps/mwiniimporter/importer.hpp @@ -17,19 +17,18 @@ class MwIniImporter { MwIniImporter(); void setInputEncoding(const ToUTF8::FromType& encoding); - void setVerbose(bool verbose); - 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 importArchives(multistrmap &cfg, multistrmap &ini); - void writeToFile(boost::iostreams::stream &out, multistrmap &cfg); - + void setVerbose(const bool verbose); + multistrmap loadIniFile(const std::string& filename) const; + static multistrmap loadCfgFile(const std::string& filename); + void merge(multistrmap &cfg, const multistrmap &ini) const; + void mergeFallback(multistrmap &cfg, const multistrmap &ini) const; + void importGameFiles(multistrmap &cfg, const multistrmap &ini) const; + void importArchives(multistrmap &cfg, const multistrmap &ini) const; + static void writeToFile(boost::iostreams::stream &out, const multistrmap &cfg); + private: - void insertMultistrmap(multistrmap &cfg, std::string key, std::string value); - std::string numberToString(int n); - std::string toUTF8(const std::string &str); + static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value); + static std::string numberToString(const int n); bool mVerbose; strmap mMergeMap; std::vector mMergeFallback; From d26e721d102f85d3845b036188b353a1fed994a2 Mon Sep 17 00:00:00 2001 From: Thoronador Date: Mon, 17 Jun 2013 18:47:12 +0200 Subject: [PATCH 149/213] no const for int and bool --- apps/mwiniimporter/importer.cpp | 4 ++-- apps/mwiniimporter/importer.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index e5d4dd2ca..d5d6a3c84 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -635,11 +635,11 @@ MwIniImporter::MwIniImporter() } } -void MwIniImporter::setVerbose(const bool verbose) { +void MwIniImporter::setVerbose(bool verbose) { mVerbose = verbose; } -std::string MwIniImporter::numberToString(const int n) { +std::string MwIniImporter::numberToString(int n) { std::stringstream str; str << n; return str.str(); diff --git a/apps/mwiniimporter/importer.hpp b/apps/mwiniimporter/importer.hpp index 362b8c29c..784980e09 100644 --- a/apps/mwiniimporter/importer.hpp +++ b/apps/mwiniimporter/importer.hpp @@ -17,7 +17,7 @@ class MwIniImporter { MwIniImporter(); void setInputEncoding(const ToUTF8::FromType& encoding); - void setVerbose(const bool verbose); + void setVerbose(bool verbose); multistrmap loadIniFile(const std::string& filename) const; static multistrmap loadCfgFile(const std::string& filename); void merge(multistrmap &cfg, const multistrmap &ini) const; @@ -28,7 +28,7 @@ class MwIniImporter { private: static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value); - static std::string numberToString(const int n); + static std::string numberToString(int n); bool mVerbose; strmap mMergeMap; std::vector mMergeFallback; From 09cc57381a943c17dd0de1aa6d77e65169448ac8 Mon Sep 17 00:00:00 2001 From: Glorf Date: Tue, 18 Jun 2013 00:43:31 +0200 Subject: [PATCH 150/213] Bugfix #809 --- apps/mwiniimporter/main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/mwiniimporter/main.cpp b/apps/mwiniimporter/main.cpp index c9d88c0bb..510b0c4a0 100644 --- a/apps/mwiniimporter/main.cpp +++ b/apps/mwiniimporter/main.cpp @@ -55,10 +55,8 @@ int main(int argc, char *argv[]) { std::cerr << "ini file does not exist" << std::endl; return -3; } - if(!boost::filesystem::exists(cfgFile)) { + if(!boost::filesystem::exists(cfgFile)) std::cerr << "cfg file does not exist" << std::endl; - return -4; - } MwIniImporter importer; importer.setVerbose(vm.count("verbose")); From 84a8ea4ef7b8fc4110552f4348d9a1826a3192e0 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 18 Jun 2013 14:31:47 +0200 Subject: [PATCH 151/213] static sdl2 compilation option for Unixes that are not Apple --- CMakeLists.txt | 1 + cmake/FindSDL2.cmake | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index df3b95eee..ec8c7049b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_ 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) option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE) +option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE) # Apps and tools option(BUILD_BSATOOL "build BSA extractor" OFF) diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake index e0c7feea3..70e607a89 100644 --- a/cmake/FindSDL2.cmake +++ b/cmake/FindSDL2.cmake @@ -183,3 +183,11 @@ INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) + +IF(SDL2_STATIC) + if (UNIX AND NOT APPLE) + EXECUTE_PROCESS(COMMAND sdl2-config --static-libs OUTPUT_VARIABLE SDL2_LINK_FLAGS) + STRING(REGEX REPLACE "(\r?\n)+$" "" SDL2_LINK_FLAGS "${SDL2_LINK_FLAGS}") + SET(SDL2_LIBRARY ${SDL2_LINK_FLAGS}) + ENDIF() +ENDIF(SDL2_STATIC) From 0d1e38740b0ed05f13009b9724cbdcab28c5c28a Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 18 Jun 2013 15:23:04 +0200 Subject: [PATCH 152/213] should fix travis building problems with sdl2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 374b38ce0..6b348fe50 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_install: - sudo apt-get install -qq libopenal-dev libmpg123-dev libsndfile1-dev - sudo apt-get install -qq libcg nvidia-cg-toolkit - sudo apt-get install -qq libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libswscale-dev libpostproc-dev - - sudo apt-get install -qq libois-dev libbullet-dev libogre-static-dev libmygui-static-dev + - sudo apt-get install -qq libois-dev libbullet-dev libogre-static-dev libmygui-static-dev libsdl2-static-dev - sudo mkdir /usr/src/gtest/build - cd /usr/src/gtest/build - sudo cmake .. -DBUILD_SHARED_LIBS=1 From 5832467c1d4a90deddb6a9c75cc859e0d6b1f673 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 18 Jun 2013 15:27:24 +0200 Subject: [PATCH 153/213] travis cleanup, remove CG and OIS --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6b348fe50..07e0280ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,9 +14,8 @@ before_install: - sudo apt-get install -qq libboost-all-dev libgtest-dev google-mock libzzip-dev - sudo apt-get install -qq libqt4-dev libxaw7-dev libxrandr-dev libfreeimage-dev libpng-dev - sudo apt-get install -qq libopenal-dev libmpg123-dev libsndfile1-dev - - sudo apt-get install -qq libcg nvidia-cg-toolkit - sudo apt-get install -qq libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libswscale-dev libpostproc-dev - - sudo apt-get install -qq libois-dev libbullet-dev libogre-static-dev libmygui-static-dev libsdl2-static-dev + - sudo apt-get install -qq libbullet-dev libogre-static-dev libmygui-static-dev libsdl2-static-dev - sudo mkdir /usr/src/gtest/build - cd /usr/src/gtest/build - sudo cmake .. -DBUILD_SHARED_LIBS=1 From 812f0b1b620626b73e15f8772c5210029a2813f7 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 18 Jun 2013 15:32:58 +0200 Subject: [PATCH 154/213] use static sdl2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 07e0280ab..5c69f49f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ before_script: - cd - - mkdir build - cd build - - cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1 + - cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBOOST_STATIC=1 -DSDL2_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1 script: - make -j4 after_script: From 4e8e048968c5c20b0b4e71c66449f37f28bd177e Mon Sep 17 00:00:00 2001 From: vorenon Date: Wed, 19 Jun 2013 01:46:38 +0200 Subject: [PATCH 155/213] Added missing click sounds to dialogue --- apps/openmw/mwgui/dialogue.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 8a57234b8..c9a780691 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -7,6 +7,7 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwmechanics/npcstats.hpp" @@ -224,16 +225,22 @@ namespace MWGui void Choice::activated() { + + MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.0, 1.0); MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId); } void Topic::activated() { + + MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(mTopicId)); } void Goodbye::activated() { + + MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f); MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); } From 04d90b4c47e140cec53750d523378d2cf9938387 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Wed, 19 Jun 2013 03:24:30 +0200 Subject: [PATCH 156/213] Type of weather changed from string to enum. --- apps/openmw/mwbase/world.hpp | 2 +- apps/openmw/mwworld/weather.cpp | 216 ++++++++++++++----------------- apps/openmw/mwworld/weather.hpp | 33 +++-- apps/openmw/mwworld/worldimp.cpp | 2 +- apps/openmw/mwworld/worldimp.hpp | 2 +- 5 files changed, 128 insertions(+), 127 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 86a6a89d2..8a83aaf86 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -191,7 +191,7 @@ namespace MWBase virtual bool toggleSky() = 0; ///< \return Resulting mode - virtual void changeWeather(const std::string& region, unsigned int id) = 0; + virtual void changeWeather(const std::string& region, int id) = 0; virtual int getCurrentWeather() const = 0; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 8b3c5f6ff..c09d70623 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -31,35 +31,62 @@ namespace } } -void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name) +std::string Weather::weatherTypeToStr(Weather::Type type) { - std::string upper=name; - upper[0]=toupper(name[0]); - weather.mCloudsMaximumPercent = mFallback->getFallbackFloat("Weather_"+upper+"_Clouds_Maximum_Percent"); - weather.mTransitionDelta = mFallback->getFallbackFloat("Weather_"+upper+"_Transition_Delta"); - weather.mSkySunriseColor=mFallback->getFallbackColour("Weather_"+upper+"_Sky_Sunrise_Color"); - weather.mSkyDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Day_Color"); - weather.mSkySunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Sunset_Color"); - weather.mSkyNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Night_Color"); - weather.mFogSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Sunrise_Color"); - weather.mFogDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Day_Color"); - weather.mFogSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Sunset_Color"); - weather.mFogNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Night_Color"); - weather.mAmbientSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Sunrise_Color"); - weather.mAmbientDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Day_Color"); - weather.mAmbientSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Sunset_Color"); - weather.mAmbientNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Night_Color"); - weather.mSunSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Sunrise_Color"); - weather.mSunDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Day_Color"); - weather.mSunSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Sunset_Color"); - weather.mSunNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Night_Color"); - weather.mSunDiscSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Disc_Sunset_Color"); - weather.mLandFogDayDepth = mFallback->getFallbackFloat("Weather_"+upper+"_Land_Fog_Day_Depth"); - weather.mLandFogNightDepth = mFallback->getFallbackFloat("Weather_"+upper+"_Land_Fog_Night_Depth"); - weather.mWindSpeed = mFallback->getFallbackFloat("Weather_"+upper+"_Wind_Speed"); - weather.mCloudSpeed = mFallback->getFallbackFloat("Weather_"+upper+"_Cloud_Speed"); - weather.mGlareView = mFallback->getFallbackFloat("Weather_"+upper+"_Glare_View"); - mWeatherSettings[name] = weather; + switch (type) { + case Type_Clear: + return "Clear"; + case Type_Cloudy: + return "Cloudy"; + case Type_Foggy: + return "Foggy"; + case Type_Overcast: + return "Overcast"; + case Type_Rain: + return "Rain"; + case Type_Thunderstorm: + return "Thunderstorm"; + case Type_Ashstorm: + return "Ashstorm"; + case Type_Blight: + return "Blight"; + case Type_Snow: + return "Snow"; + case Type_Blizzard: + return "Blizzard"; + default: // Type_Unknown + return ""; + } +} + +void WeatherManager::setFallbackWeather(Weather& weather, Weather::Type type) +{ + const std::string weatherName = Weather::weatherTypeToStr(type); + weather.mCloudsMaximumPercent = mFallback->getFallbackFloat("Weather_"+weatherName+"_Clouds_Maximum_Percent"); + weather.mTransitionDelta = mFallback->getFallbackFloat("Weather_"+weatherName+"_Transition_Delta"); + weather.mSkySunriseColor= mFallback->getFallbackColour("Weather_"+weatherName+"_Sky_Sunrise_Color"); + weather.mSkyDayColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sky_Day_Color"); + weather.mSkySunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sky_Sunset_Color"); + weather.mSkyNightColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sky_Night_Color"); + weather.mFogSunriseColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Fog_Sunrise_Color"); + weather.mFogDayColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Fog_Day_Color"); + weather.mFogSunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Fog_Sunset_Color"); + weather.mFogNightColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Fog_Night_Color"); + weather.mAmbientSunriseColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Ambient_Sunrise_Color"); + weather.mAmbientDayColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Ambient_Day_Color"); + weather.mAmbientSunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Ambient_Sunset_Color"); + weather.mAmbientNightColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Ambient_Night_Color"); + weather.mSunSunriseColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Sunrise_Color"); + weather.mSunDayColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Day_Color"); + weather.mSunSunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Sunset_Color"); + weather.mSunNightColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Night_Color"); + weather.mSunDiscSunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Disc_Sunset_Color"); + weather.mLandFogDayDepth = mFallback->getFallbackFloat("Weather_"+weatherName+"_Land_Fog_Day_Depth"); + weather.mLandFogNightDepth = mFallback->getFallbackFloat("Weather_"+weatherName+"_Land_Fog_Night_Depth"); + weather.mWindSpeed = mFallback->getFallbackFloat("Weather_"+weatherName+"_Wind_Speed"); + weather.mCloudSpeed = mFallback->getFallbackFloat("Weather_"+weatherName+"_Cloud_Speed"); + weather.mGlareView = mFallback->getFallbackFloat("Weather_"+weatherName+"_Glare_View"); + mWeatherSettings[type] = weather; } @@ -91,7 +118,7 @@ float WeatherManager::calculateAngleFade (const std::string& moonName, float ang } WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fallback* fallback) : - mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), + mHour(14), mCurrentWeather(Weather::Type_Clear), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0), mMonth(0), mDay(0), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mRendering(rendering) @@ -125,53 +152,53 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa //Weather Weather clear; clear.mCloudTexture = "tx_sky_clear.dds"; - setFallbackWeather(clear,"clear"); + setFallbackWeather(clear, Weather::Type_Clear); Weather cloudy; cloudy.mCloudTexture = "tx_sky_cloudy.dds"; - setFallbackWeather(cloudy,"cloudy"); + setFallbackWeather(cloudy, Weather::Type_Cloudy); Weather foggy; foggy.mCloudTexture = "tx_sky_foggy.dds"; - setFallbackWeather(foggy,"foggy"); + setFallbackWeather(foggy, Weather::Type_Foggy); Weather thunderstorm; thunderstorm.mCloudTexture = "tx_sky_thunder.dds"; thunderstorm.mRainLoopSoundID = "rain heavy"; - setFallbackWeather(thunderstorm,"thunderstorm"); + setFallbackWeather(thunderstorm, Weather::Type_Thunderstorm); Weather rain; rain.mCloudTexture = "tx_sky_rainy.dds"; rain.mRainLoopSoundID = "rain"; - setFallbackWeather(rain,"rain"); + setFallbackWeather(rain, Weather::Type_Rain); Weather overcast; overcast.mCloudTexture = "tx_sky_overcast.dds"; - setFallbackWeather(overcast,"overcast"); + setFallbackWeather(overcast, Weather::Type_Overcast); Weather ashstorm; ashstorm.mCloudTexture = "tx_sky_ashstorm.dds"; ashstorm.mAmbientLoopSoundID = "ashstorm"; - setFallbackWeather(ashstorm,"ashstorm"); + setFallbackWeather(ashstorm, Weather::Type_Ashstorm); Weather blight; blight.mCloudTexture = "tx_sky_blight.dds"; blight.mAmbientLoopSoundID = "blight"; - setFallbackWeather(blight,"blight"); + setFallbackWeather(blight, Weather::Type_Blight); Weather snow; snow.mCloudTexture = "tx_bm_sky_snow.dds"; - setFallbackWeather(snow, "snow"); + setFallbackWeather(snow, Weather::Type_Snow); Weather blizzard; blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds"; blizzard.mAmbientLoopSoundID = "BM Blizzard"; - setFallbackWeather(blizzard,"blizzard"); + setFallbackWeather(blizzard, Weather::Type_Blizzard); } -void WeatherManager::setWeather(const String& weather, bool instant) +void WeatherManager::setWeather(Weather::Type weatherType, bool instant) { - if (weather == mCurrentWeather && mNextWeather == "") + if (weatherType == mCurrentWeather && mNextWeather == Weather::Type_Unknown) { mFirstUpdate = false; return; @@ -179,27 +206,27 @@ void WeatherManager::setWeather(const String& weather, bool instant) if (instant || mFirstUpdate) { - mNextWeather = ""; - mCurrentWeather = weather; + mNextWeather = Weather::Type_Unknown; + mCurrentWeather = weatherType; } else { - if (mNextWeather != "") + if (mNextWeather != Weather::Type_Unknown) { // transition more than 50% finished? if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600) <= 0.5) mCurrentWeather = mNextWeather; } - mNextWeather = weather; + mNextWeather = weatherType; mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600; } mFirstUpdate = false; } -WeatherResult WeatherManager::getResult(const String& weather) +WeatherResult WeatherManager::getResult(Weather::Type weatherType) { - const Weather& current = mWeatherSettings[weather]; + const Weather& current = mWeatherSettings[weatherType]; WeatherResult result; result.mCloudTexture = current.mCloudTexture; @@ -336,10 +363,10 @@ void WeatherManager::update(float duration) mCurrentRegion = regionstr; mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; - std::string weather = "clear"; + Weather::Type weatherType = Weather::Type_Clear; if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) - weather = mRegionOverrides[regionstr]; + weatherType = mRegionOverrides[regionstr]; else { // get weather probabilities for the current region @@ -365,44 +392,44 @@ void WeatherManager::update(float duration) float random = ((rand()%100)/100.f) * total; if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) - weather = "blizzard"; + weatherType = Weather::Type_Blizzard; else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear) - weather = "snow"; + weatherType = Weather::Type_Snow; else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear) - weather = "blight"; + weatherType = Weather::Type_Blight; else if (random >= thunder+rain+overcast+foggy+cloudy+clear) - weather = "ashstorm"; + weatherType = Weather::Type_Ashstorm; else if (random >= rain+overcast+foggy+cloudy+clear) - weather = "thunderstorm"; + weatherType = Weather::Type_Thunderstorm; else if (random >= overcast+foggy+cloudy+clear) - weather = "rain"; + weatherType = Weather::Type_Rain; else if (random >= foggy+cloudy+clear) - weather = "overcast"; + weatherType = Weather::Type_Overcast; else if (random >= cloudy+clear) - weather = "foggy"; + weatherType = Weather::Type_Foggy; else if (random >= clear) - weather = "cloudy"; + weatherType = Weather::Type_Cloudy; else - weather = "clear"; + weatherType = Weather::Type_Clear; } } - setWeather(weather, false); + setWeather(weatherType, false); } WeatherResult result; - if (mNextWeather != "") + if (mNextWeather != Weather::Type_Unknown) { mRemainingTransitionTime -= timePassed; if (mRemainingTransitionTime < 0) { mCurrentWeather = mNextWeather; - mNextWeather = ""; + mNextWeather = Weather::Type_Unknown; } } - if (mNextWeather != "") + if (mNextWeather != Weather::Type_Unknown) result = transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600))); else result = getResult(mCurrentWeather); @@ -494,7 +521,7 @@ void WeatherManager::update(float duration) mRendering->getSkyManager()->secundaDisable(); } - if (mCurrentWeather == "thunderstorm" && mNextWeather == "" && exterior) + if (mCurrentWeather == Weather::Type_Thunderstorm && mNextWeather == Weather::Type_Unknown && exterior) { if (mThunderFlash > 0) { @@ -555,7 +582,7 @@ void WeatherManager::update(float duration) } // play sounds - std::string ambientSnd = (mNextWeather == "" ? mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID : ""); + std::string ambientSnd = (mNextWeather == Weather::Type_Unknown ? mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID : ""); if (!exterior) ambientSnd = ""; if (ambientSnd != "") { @@ -566,7 +593,7 @@ void WeatherManager::update(float duration) } } - std::string rainSnd = (mNextWeather == "" ? mWeatherSettings[mCurrentWeather].mRainLoopSoundID : ""); + std::string rainSnd = (mNextWeather == Weather::Type_Unknown ? mWeatherSettings[mCurrentWeather].mRainLoopSoundID : ""); if (!exterior) rainSnd = ""; if (rainSnd != "") { @@ -605,66 +632,23 @@ void WeatherManager::setDate(const int day, const int month) unsigned int WeatherManager::getWeatherID() const { // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather - - if (mCurrentWeather == "clear") - return 0; - else if (mCurrentWeather == "cloudy") - return 1; - else if (mCurrentWeather == "foggy") - return 2; - else if (mCurrentWeather == "overcast") - return 3; - else if (mCurrentWeather == "rain") - return 4; - else if (mCurrentWeather == "thunderstorm") - return 5; - else if (mCurrentWeather == "ashstorm") - return 6; - else if (mCurrentWeather == "blight") - return 7; - else if (mCurrentWeather == "snow") - return 8; - else if (mCurrentWeather == "blizzard") - return 9; - - else - return 0; + return mCurrentWeather; } -void WeatherManager::changeWeather(const std::string& region, const unsigned int id) +void WeatherManager::changeWeather(const std::string& region, const int id) { // make sure this region exists MWBase::Environment::get().getWorld()->getStore().get().find(region); - std::string weather; - if (id==0) - weather = "clear"; - else if (id==1) - weather = "cloudy"; - else if (id==2) - weather = "foggy"; - else if (id==3) - weather = "overcast"; - else if (id==4) - weather = "rain"; - else if (id==5) - weather = "thunderstorm"; - else if (id==6) - weather = "ashstorm"; - else if (id==7) - weather = "blight"; - else if (id==8) - weather = "snow"; - else if (id==9) - weather = "blizzard"; - else - weather = "clear"; + Weather::Type weatherType = Weather::Type_Clear; + if (id >= Weather::Type_Clear && id < Weather::Type_Unknown) + weatherType = (Weather::Type)id; - mRegionOverrides[Misc::StringUtils::lowerCase(region)] = weather; + mRegionOverrides[Misc::StringUtils::lowerCase(region)] = weatherType; std::string playerRegion = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion; if (Misc::StringUtils::ciEqual(region, playerRegion)) - setWeather(weather); + setWeather(weatherType); } float WeatherManager::getWindSpeed() const diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 081bd7f87..08e9c017d 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -50,6 +50,21 @@ namespace MWWorld /// Defines a single weather setting (according to INI) struct Weather { + enum Type + { + Type_Clear = 0, + Type_Cloudy, + Type_Foggy, + Type_Overcast, + Type_Rain, + Type_Thunderstorm, + Type_Ashstorm, + Type_Blight, + Type_Snow, + Type_Blizzard, + Type_Unknown + }; + Ogre::String mCloudTexture; // Sky (atmosphere) colors @@ -106,6 +121,8 @@ namespace MWWorld Ogre::String mRainLoopSoundID; /// \todo disease chance + + static std::string weatherTypeToStr(Weather::Type type); }; /// @@ -121,7 +138,7 @@ namespace MWWorld * @param region that should be changed * @param ID of the weather setting to shift to */ - void changeWeather(const std::string& region, const unsigned int id); + void changeWeather(const std::string& region, const int id); /** * Per-frame update @@ -147,17 +164,17 @@ namespace MWWorld int mDay, mMonth; float mWindSpeed; MWWorld::Fallback* mFallback; - void setFallbackWeather(Weather& weather,const std::string& name); + void setFallbackWeather(Weather& weather, Weather::Type type); MWRender::RenderingManager* mRendering; - std::map mWeatherSettings; + std::map mWeatherSettings; - std::map mRegionOverrides; + std::map mRegionOverrides; std::vector mSoundsPlaying; - Ogre::String mCurrentWeather; - Ogre::String mNextWeather; + Weather::Type mCurrentWeather; + Weather::Type mNextWeather; std::string mCurrentRegion; @@ -172,12 +189,12 @@ namespace MWWorld double mTimePassed; // time passed since last update WeatherResult transition(const float factor); - WeatherResult getResult(const Ogre::String& weather); + WeatherResult getResult(Weather::Type weatherType); float calculateHourFade (const std::string& moonName) const; float calculateAngleFade (const std::string& moonName, float angle) const; - void setWeather(const Ogre::String& weather, bool instant=false); + void setWeather(Weather::Type weatherType, bool instant=false); float mSunriseTime; float mSunsetTime; float mSunriseDuration; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 16cba2ea8..ee642f869 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1371,7 +1371,7 @@ namespace MWWorld return mWeatherManager->getWeatherID(); } - void World::changeWeather(const std::string& region, const unsigned int id) + void World::changeWeather(const std::string& region, const int id) { mWeatherManager->changeWeather(region, id); } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 12438efd4..35eba979f 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -225,7 +225,7 @@ namespace MWWorld virtual bool toggleSky(); ///< \return Resulting mode - virtual void changeWeather (const std::string& region, unsigned int id); + virtual void changeWeather (const std::string& region, int id); virtual int getCurrentWeather() const; From f01aa8f55e76b3a6ada1ab81c009db66e648f933 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Wed, 19 Jun 2013 04:57:36 +0200 Subject: [PATCH 157/213] Simpler statistical calculation of next weather; minus before parens. --- apps/openmw/mwworld/weather.cpp | 70 +++++++++++++++------------------ 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index c09d70623..bff52dfe8 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -375,42 +375,36 @@ void WeatherManager::update(float duration) if (region != 0) { - float clear = region->mData.mClear/255.f; - float cloudy = region->mData.mCloudy/255.f; - float foggy = region->mData.mFoggy/255.f; - float overcast = region->mData.mOvercast/255.f; - float rain = region->mData.mRain/255.f; - float thunder = region->mData.mThunder/255.f; - float ash = region->mData.mAsh/255.f; - float blight = region->mData.mBlight/255.f; - float snow = region->mData.mA/255.f; - float blizzard = region->mData.mB/255.f; - - // re-scale to 100 percent - const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard; - - float random = ((rand()%100)/100.f) * total; - - if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) - weatherType = Weather::Type_Blizzard; - else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear) - weatherType = Weather::Type_Snow; - else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear) - weatherType = Weather::Type_Blight; - else if (random >= thunder+rain+overcast+foggy+cloudy+clear) - weatherType = Weather::Type_Ashstorm; - else if (random >= rain+overcast+foggy+cloudy+clear) - weatherType = Weather::Type_Thunderstorm; - else if (random >= overcast+foggy+cloudy+clear) - weatherType = Weather::Type_Rain; - else if (random >= foggy+cloudy+clear) - weatherType = Weather::Type_Overcast; - else if (random >= cloudy+clear) - weatherType = Weather::Type_Foggy; - else if (random >= clear) - weatherType = Weather::Type_Cloudy; - else - weatherType = Weather::Type_Clear; + /* + * All probabilities must add to 100 (responsibility of the user). + * If chances A and B has values 30 and 70 then by generating + * 100 numbers 1..100, 30% will be lesser or equal 30 and + * 70% will be greater than 30 (in theory). + */ + const int probability[] = { + region->mData.mClear, + region->mData.mCloudy, + region->mData.mFoggy, + region->mData.mOvercast, + region->mData.mRain, + region->mData.mThunder, + region->mData.mAsh, + region->mData.mBlight, + region->mData.mA, + region->mData.mB + }; // 10 elements + + int chance = (rand() % 100) + 1; // 1..100 + int sum = 0; + for (int i = 0; i < 10; ++i) + { + sum += probability[i]; + if (chance < sum) + { + weatherType = (Weather::Type)i; + break; + } + } } } @@ -461,8 +455,8 @@ void WeatherManager::update(float duration) int facing = (mHour > 13.f) ? 1 : -1; Vector3 final( - -(1 - height) * facing, - -(1 - height) * facing, + (height - 1) * facing, + (height - 1) * facing, height); mRendering->setSunDirection(final); From 8a45686e0a98cf254fbd8b780d3016d196c9db89 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Wed, 19 Jun 2013 06:50:36 +0200 Subject: [PATCH 158/213] WeatherResult added as member variable. --- apps/openmw/mwworld/weather.cpp | 148 +++++++++++++++----------------- apps/openmw/mwworld/weather.hpp | 5 +- 2 files changed, 74 insertions(+), 79 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index bff52dfe8..8cec967ad 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -224,32 +224,31 @@ void WeatherManager::setWeather(Weather::Type weatherType, bool instant) mFirstUpdate = false; } -WeatherResult WeatherManager::getResult(Weather::Type weatherType) +void WeatherManager::setResult(Weather::Type weatherType) { const Weather& current = mWeatherSettings[weatherType]; - WeatherResult result; - - result.mCloudTexture = current.mCloudTexture; - result.mCloudBlendFactor = 0; - result.mCloudOpacity = current.mCloudsMaximumPercent; - result.mWindSpeed = current.mWindSpeed; - result.mCloudSpeed = current.mCloudSpeed; - result.mGlareView = current.mGlareView; - result.mAmbientLoopSoundID = current.mAmbientLoopSoundID; - result.mSunColor = current.mSunDiscSunsetColor; + + mResult.mCloudTexture = current.mCloudTexture; + mResult.mCloudBlendFactor = 0; + mResult.mCloudOpacity = current.mCloudsMaximumPercent; + mResult.mWindSpeed = current.mWindSpeed; + mResult.mCloudSpeed = current.mCloudSpeed; + mResult.mGlareView = current.mGlareView; + mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID; + mResult.mSunColor = current.mSunDiscSunsetColor; - result.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1); + mResult.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1); - result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth; + mResult.mFogDepth = mResult.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth; // night if (mHour <= mNightEnd || mHour >= mNightStart + 1) { - result.mFogColor = current.mFogNightColor; - result.mAmbientColor = current.mAmbientNightColor; - result.mSunColor = current.mSunNightColor; - result.mSkyColor = current.mSkyNightColor; - result.mNightFade = 1.f; + mResult.mFogColor = current.mFogNightColor; + mResult.mAmbientColor = current.mAmbientNightColor; + mResult.mSunColor = current.mSunNightColor; + mResult.mSkyColor = current.mSkyNightColor; + mResult.mNightFade = 1.f; } // sunrise @@ -260,31 +259,31 @@ WeatherResult WeatherManager::getResult(Weather::Type weatherType) // fade in float advance = mSunriseTime - mHour; float factor = advance / 0.5f; - result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor); - result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor); - result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor, factor); - result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor, factor); - result.mNightFade = factor; + mResult.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor); + mResult.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor); + mResult.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor, factor); + mResult.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor, factor); + mResult.mNightFade = factor; } else //if (mHour >= 6) { // fade out float advance = mHour - mSunriseTime; float factor = advance / 3.f; - result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor); - result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor); - result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor, factor); - result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor, factor); + mResult.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor); + mResult.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor); + mResult.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor, factor); + mResult.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor, factor); } } // day else if (mHour >= mDayStart + 1 && mHour <= mDayEnd - 1) { - result.mFogColor = current.mFogDayColor; - result.mAmbientColor = current.mAmbientDayColor; - result.mSunColor = current.mSunDayColor; - result.mSkyColor = current.mSkyDayColor; + mResult.mFogColor = current.mFogDayColor; + mResult.mAmbientColor = current.mAmbientDayColor; + mResult.mSunColor = current.mSunDayColor; + mResult.mSkyColor = current.mSkyDayColor; } // sunset @@ -295,54 +294,51 @@ WeatherResult WeatherManager::getResult(Weather::Type weatherType) // fade in float advance = (mDayEnd + 1) - mHour; float factor = (advance / 2); - result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor); - result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor); - result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor, factor); - result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor, factor); + mResult.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor); + mResult.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor); + mResult.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor, factor); + mResult.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor, factor); } else //if (mHour >= 19) { // fade out float advance = mHour - (mDayEnd + 1); float factor = advance / 2.f; - result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor); - result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor); - result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor, factor); - result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor, factor); - result.mNightFade = factor; + mResult.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor); + mResult.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor); + mResult.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor, factor); + mResult.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor, factor); + mResult.mNightFade = factor; } } - - return result; } -WeatherResult WeatherManager::transition(float factor) +void WeatherManager::transition(float factor) { - const WeatherResult& current = getResult(mCurrentWeather); - const WeatherResult& other = getResult(mNextWeather); - WeatherResult result; - - result.mCloudTexture = current.mCloudTexture; - result.mNextCloudTexture = other.mCloudTexture; - result.mCloudBlendFactor = factor; - - result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor); - result.mFogColor = lerp(current.mFogColor, other.mFogColor, factor); - result.mSunColor = lerp(current.mSunColor, other.mSunColor, factor); - result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor, factor); - - result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor, factor); - result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor, factor); - result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth, factor); - result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed, factor); - result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed, factor); - result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor); - result.mGlareView = lerp(current.mGlareView, other.mGlareView, factor); - result.mNightFade = lerp(current.mNightFade, other.mNightFade, factor); - - result.mNight = current.mNight; - - return result; + setResult(mCurrentWeather); + const WeatherResult current = mResult; + setResult(mNextWeather); + const WeatherResult other = mResult; + + mResult.mCloudTexture = current.mCloudTexture; + mResult.mNextCloudTexture = other.mCloudTexture; + mResult.mCloudBlendFactor = factor; + + mResult.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor); + mResult.mFogColor = lerp(current.mFogColor, other.mFogColor, factor); + mResult.mSunColor = lerp(current.mSunColor, other.mSunColor, factor); + mResult.mSkyColor = lerp(current.mSkyColor, other.mSkyColor, factor); + + mResult.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor, factor); + mResult.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor, factor); + mResult.mFogDepth = lerp(current.mFogDepth, other.mFogDepth, factor); + mResult.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed, factor); + mResult.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed, factor); + mResult.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor); + mResult.mGlareView = lerp(current.mGlareView, other.mGlareView, factor); + mResult.mNightFade = lerp(current.mNightFade, other.mNightFade, factor); + + mResult.mNight = current.mNight; } void WeatherManager::update(float duration) @@ -411,8 +407,6 @@ void WeatherManager::update(float duration) setWeather(weatherType, false); } - WeatherResult result; - if (mNextWeather != Weather::Type_Unknown) { mRemainingTransitionTime -= timePassed; @@ -424,13 +418,13 @@ void WeatherManager::update(float duration) } if (mNextWeather != Weather::Type_Unknown) - result = transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600))); + transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600))); else - result = getResult(mCurrentWeather); + setResult(mCurrentWeather); - mWindSpeed = result.mWindSpeed; + mWindSpeed = mResult.mWindSpeed; - mRendering->configureFog(result.mFogDepth, result.mFogColor); + mRendering->configureFog(mResult.mFogDepth, mResult.mFogColor); // disable sun during night if (mHour >= mNightStart || mHour <= mSunriseTime) @@ -562,11 +556,11 @@ void WeatherManager::update(float duration) else mRendering->getSkyManager()->setLightningStrength(0.f); - mRendering->setAmbientColour(result.mAmbientColor); + mRendering->setAmbientColour(mResult.mAmbientColor); mRendering->sunEnable(false); - mRendering->setSunColour(result.mSunColor); + mRendering->setSunColour(mResult.mSunColor); - mRendering->getSkyManager()->setWeather(result); + mRendering->getSkyManager()->setWeather(mResult); } else { diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 08e9c017d..f51a365c6 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -188,13 +188,14 @@ namespace MWWorld double mTimePassed; // time passed since last update - WeatherResult transition(const float factor); - WeatherResult getResult(Weather::Type weatherType); + void transition(const float factor); + void setResult(Weather::Type weatherType); float calculateHourFade (const std::string& moonName) const; float calculateAngleFade (const std::string& moonName, float angle) const; void setWeather(Weather::Type weatherType, bool instant=false); + WeatherResult mResult; float mSunriseTime; float mSunsetTime; float mSunriseDuration; From bf31e5385c041342f5633ee9db66120dd14e97e6 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Wed, 19 Jun 2013 16:18:43 +0200 Subject: [PATCH 159/213] Removal of duplicit exterior checking and unneded string copiing. --- apps/openmw/mwworld/weather.cpp | 376 ++++++++++++++++---------------- apps/openmw/mwworld/weather.hpp | 8 + 2 files changed, 200 insertions(+), 184 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 8cec967ad..89c5892a9 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -348,243 +348,210 @@ void WeatherManager::update(float duration) mWeatherUpdateTime -= timePassed; - bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); - - if (exterior) + const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); + if (!exterior) { - std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion); + mRendering->sunDisable(false); + mRendering->skyDisable(); + mRendering->getSkyManager()->setLightningStrength(0.f); + stopSounds(true); + return; + } - if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) - { - mCurrentRegion = regionstr; - mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; + // Exterior + std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion); - Weather::Type weatherType = Weather::Type_Clear; + if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) + { + mCurrentRegion = regionstr; + mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; - if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) - weatherType = mRegionOverrides[regionstr]; - else - { - // get weather probabilities for the current region - const ESM::Region *region = + Weather::Type weatherType = Weather::Type_Clear; + + if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) + weatherType = mRegionOverrides[regionstr]; + else + { + // get weather probabilities for the current region + const ESM::Region *region = MWBase::Environment::get().getWorld()->getStore().get().search (regionstr); - if (region != 0) - { - /* - * All probabilities must add to 100 (responsibility of the user). - * If chances A and B has values 30 and 70 then by generating - * 100 numbers 1..100, 30% will be lesser or equal 30 and - * 70% will be greater than 30 (in theory). - */ - const int probability[] = { - region->mData.mClear, - region->mData.mCloudy, - region->mData.mFoggy, - region->mData.mOvercast, - region->mData.mRain, - region->mData.mThunder, - region->mData.mAsh, - region->mData.mBlight, - region->mData.mA, - region->mData.mB - }; // 10 elements - - int chance = (rand() % 100) + 1; // 1..100 - int sum = 0; - for (int i = 0; i < 10; ++i) - { - sum += probability[i]; - if (chance < sum) - { - weatherType = (Weather::Type)i; - break; - } - } - } + if (region != 0) + { + weatherType = nextWeather(region); } - - setWeather(weatherType, false); } - if (mNextWeather != Weather::Type_Unknown) + setWeather(weatherType, false); + } + + if (mNextWeather != Weather::Type_Unknown) + { + mRemainingTransitionTime -= timePassed; + if (mRemainingTransitionTime < 0) { - mRemainingTransitionTime -= timePassed; - if (mRemainingTransitionTime < 0) - { - mCurrentWeather = mNextWeather; - mNextWeather = Weather::Type_Unknown; - } + mCurrentWeather = mNextWeather; + mNextWeather = Weather::Type_Unknown; } + } - if (mNextWeather != Weather::Type_Unknown) - transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600))); - else - setResult(mCurrentWeather); + if (mNextWeather != Weather::Type_Unknown) + transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600))); + else + setResult(mCurrentWeather); - mWindSpeed = mResult.mWindSpeed; + mWindSpeed = mResult.mWindSpeed; - mRendering->configureFog(mResult.mFogDepth, mResult.mFogColor); + mRendering->configureFog(mResult.mFogDepth, mResult.mFogColor); - // disable sun during night - if (mHour >= mNightStart || mHour <= mSunriseTime) - mRendering->getSkyManager()->sunDisable(); - else - mRendering->getSkyManager()->sunEnable(); + // disable sun during night + if (mHour >= mNightStart || mHour <= mSunriseTime) + mRendering->getSkyManager()->sunDisable(); + else + mRendering->getSkyManager()->sunEnable(); - // sun angle - float height; + // sun angle + float height; - //Day duration - float dayDuration = (mNightStart - 1) - mSunriseTime; + //Day duration + float dayDuration = (mNightStart - 1) - mSunriseTime; - // rise at 6, set at 20 - if (mHour >= mSunriseTime && mHour <= mNightStart) - height = 1 - std::abs(((mHour - dayDuration) / 7.f)); - else if (mHour > mNightStart) - height = (mHour - mNightStart) / 4.f; - else //if (mHour > 0 && mHour < 6) - height = 1 - (mHour / mSunriseTime); + // rise at 6, set at 20 + if (mHour >= mSunriseTime && mHour <= mNightStart) + height = 1 - std::abs(((mHour - dayDuration) / 7.f)); + else if (mHour > mNightStart) + height = (mHour - mNightStart) / 4.f; + else //if (mHour > 0 && mHour < 6) + height = 1 - (mHour / mSunriseTime); - int facing = (mHour > 13.f) ? 1 : -1; + int facing = (mHour > 13.f) ? 1 : -1; - Vector3 final( + Vector3 final( (height - 1) * facing, (height - 1) * facing, height); - mRendering->setSunDirection(final); - - /* - * TODO: import separated fadeInStart/Finish, fadeOutStart/Finish - * for masser and secunda - */ - - float fadeOutFinish=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Finish"); - float fadeInStart=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Start"); - - //moon calculations - float moonHeight; - if (mHour >= fadeInStart) - moonHeight = mHour - fadeInStart; - else if (mHour <= fadeOutFinish) - moonHeight = mHour + fadeOutFinish; - else - moonHeight = 0; + mRendering->setSunDirection(final); - moonHeight /= (24.f - (fadeInStart - fadeOutFinish)); + /* + * TODO: import separated fadeInStart/Finish, fadeOutStart/Finish + * for masser and secunda + */ - if (moonHeight != 0) - { - int facing = (moonHeight <= 1) ? 1 : -1; - Vector3 masser( + float fadeOutFinish=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Finish"); + float fadeInStart=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Start"); + + //moon calculations + float moonHeight; + if (mHour >= fadeInStart) + moonHeight = mHour - fadeInStart; + else if (mHour <= fadeOutFinish) + moonHeight = mHour + fadeOutFinish; + else + moonHeight = 0; + + moonHeight /= (24.f - (fadeInStart - fadeOutFinish)); + + if (moonHeight != 0) + { + int facing = (moonHeight <= 1) ? 1 : -1; + Vector3 masser( (moonHeight - 1) * facing, (1 - moonHeight) * facing, moonHeight); - Vector3 secunda( + Vector3 secunda( (moonHeight - 1) * facing * 1.25, (1 - moonHeight) * facing * 0.8, moonHeight); - mRendering->getSkyManager()->setMasserDirection(masser); - mRendering->getSkyManager()->setSecundaDirection(secunda); - mRendering->getSkyManager()->masserEnable(); - mRendering->getSkyManager()->secundaEnable(); + mRendering->getSkyManager()->setMasserDirection(masser); + mRendering->getSkyManager()->setSecundaDirection(secunda); + mRendering->getSkyManager()->masserEnable(); + mRendering->getSkyManager()->secundaEnable(); - float angle = (1-moonHeight) * 90.f * facing; - float masserHourFade = calculateHourFade("Masser"); - float secundaHourFade = calculateHourFade("Secunda"); - float masserAngleFade = calculateAngleFade("Masser", angle); - float secundaAngleFade = calculateAngleFade("Secunda", angle); + float angle = (1-moonHeight) * 90.f * facing; + float masserHourFade = calculateHourFade("Masser"); + float secundaHourFade = calculateHourFade("Secunda"); + float masserAngleFade = calculateAngleFade("Masser", angle); + float secundaAngleFade = calculateAngleFade("Secunda", angle); - masserAngleFade *= masserHourFade; - secundaAngleFade *= secundaHourFade; + masserAngleFade *= masserHourFade; + secundaAngleFade *= secundaHourFade; - mRendering->getSkyManager()->setMasserFade(masserAngleFade); - mRendering->getSkyManager()->setSecundaFade(secundaAngleFade); - } - else - { - mRendering->getSkyManager()->masserDisable(); - mRendering->getSkyManager()->secundaDisable(); - } + mRendering->getSkyManager()->setMasserFade(masserAngleFade); + mRendering->getSkyManager()->setSecundaFade(secundaAngleFade); + } + else + { + mRendering->getSkyManager()->masserDisable(); + mRendering->getSkyManager()->secundaDisable(); + } - if (mCurrentWeather == Weather::Type_Thunderstorm && mNextWeather == Weather::Type_Unknown && exterior) + if (mCurrentWeather == Weather::Type_Thunderstorm && mNextWeather == Weather::Type_Unknown) + { + if (mThunderFlash > 0) { - if (mThunderFlash > 0) + // play the sound after a delay + mThunderSoundDelay -= duration; + if (mThunderSoundDelay <= 0) { - // play the sound after a delay - mThunderSoundDelay -= duration; - if (mThunderSoundDelay <= 0) - { - // pick a random sound - int sound = rand() % 4; - std::string soundname; - if (sound == 0) soundname = mThunderSoundID0; - else if (sound == 1) soundname = mThunderSoundID1; - else if (sound == 2) soundname = mThunderSoundID2; - else if (sound == 3) soundname = mThunderSoundID3; - MWBase::Environment::get().getSoundManager()->playSound(soundname, 1.0, 1.0); - mThunderSoundDelay = 1000; - } - - mThunderFlash -= duration; - if (mThunderFlash > 0) - mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold ); - else - { - srand(time(NULL)); - mThunderChanceNeeded = rand() % 100; - mThunderChance = 0; - mRendering->getSkyManager()->setLightningStrength( 0.f ); - } + // pick a random sound + int sound = rand() % 4; + std::string* soundName; + if (sound == 0) soundName = &mThunderSoundID0; + else if (sound == 1) soundName = &mThunderSoundID1; + else if (sound == 2) soundName = &mThunderSoundID2; + else if (sound == 3) soundName = &mThunderSoundID3; + MWBase::Environment::get().getSoundManager()->playSound(*soundName, 1.0, 1.0); + mThunderSoundDelay = 1000; } + + mThunderFlash -= duration; + if (mThunderFlash > 0) + mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold ); else { - // no thunder active - mThunderChance += duration*4; // chance increases by 4 percent every second - if (mThunderChance >= mThunderChanceNeeded) - { - mThunderFlash = mThunderThreshold; - - mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold ); - - mThunderSoundDelay = 0.25; - } + srand(time(NULL)); + mThunderChanceNeeded = rand() % 100; + mThunderChance = 0; + mRendering->getSkyManager()->setLightningStrength( 0.f ); } } else - mRendering->getSkyManager()->setLightningStrength(0.f); + { + // no thunder active + mThunderChance += duration*4; // chance increases by 4 percent every second + if (mThunderChance >= mThunderChanceNeeded) + { + mThunderFlash = mThunderThreshold; - mRendering->setAmbientColour(mResult.mAmbientColor); - mRendering->sunEnable(false); - mRendering->setSunColour(mResult.mSunColor); + mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold ); - mRendering->getSkyManager()->setWeather(mResult); + mThunderSoundDelay = 0.25; + } + } } else - { - mRendering->sunDisable(false); - mRendering->skyDisable(); mRendering->getSkyManager()->setLightningStrength(0.f); - } - // play sounds - std::string ambientSnd = (mNextWeather == Weather::Type_Unknown ? mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID : ""); - if (!exterior) ambientSnd = ""; - if (ambientSnd != "") + mRendering->setAmbientColour(mResult.mAmbientColor); + mRendering->sunEnable(false); + mRendering->setSunColour(mResult.mSunColor); + + mRendering->getSkyManager()->setWeather(mResult); + + + // Play sounds + if (mNextWeather == Weather::Type_Unknown) { + std::string ambientSnd = mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID; if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end()) { mSoundsPlaying.push_back(ambientSnd); MWBase::Environment::get().getSoundManager()->playSound(ambientSnd, 1.0, 1.0, MWBase::SoundManager::Play_Loop); } - } - std::string rainSnd = (mNextWeather == Weather::Type_Unknown ? mWeatherSettings[mCurrentWeather].mRainLoopSoundID : ""); - if (!exterior) rainSnd = ""; - if (rainSnd != "") - { + std::string rainSnd = mWeatherSettings[mCurrentWeather].mRainLoopSoundID; if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end()) { mSoundsPlaying.push_back(rainSnd); @@ -592,18 +559,59 @@ void WeatherManager::update(float duration) } } - // stop sounds - std::vector::iterator it=mSoundsPlaying.begin(); + stopSounds(false); +} + +void WeatherManager::stopSounds(bool stopAll) +{ + std::vector::iterator it = mSoundsPlaying.begin(); while (it!=mSoundsPlaying.end()) { - if ( *it != ambientSnd && *it != rainSnd) + if (stopAll || \ + !(*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID || \ + *it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID)) { MWBase::Environment::get().getSoundManager()->stopSound(*it); it = mSoundsPlaying.erase(it); } - else - ++it; + + ++it; + } +} + +Weather::Type WeatherManager::nextWeather(const ESM::Region* region) +{ + /* + * All probabilities must add to 100 (responsibility of the user). + * If chances A and B has values 30 and 70 then by generating + * 100 numbers 1..100, 30% will be lesser or equal 30 and + * 70% will be greater than 30 (in theory). + */ + const int probability[] = { + region->mData.mClear, + region->mData.mCloudy, + region->mData.mFoggy, + region->mData.mOvercast, + region->mData.mRain, + region->mData.mThunder, + region->mData.mAsh, + region->mData.mBlight, + region->mData.mA, + region->mData.mB + }; // 10 elements + + int chance = (rand() % 100) + 1; // 1..100 + int sum = 0; + int i = 0; + for (; i < 10; ++i) + { + sum += probability[i]; + if (chance < sum) + { + break; + } } + return (Weather::Type) i; } void WeatherManager::setHour(const float hour) diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index f51a365c6..fa305dc3c 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -4,6 +4,11 @@ #include #include +namespace ESM +{ + struct Region; +} + namespace MWRender { class RenderingManager; @@ -146,6 +151,8 @@ namespace MWWorld */ void update(float duration); + void stopSounds(bool stopAll); + void setHour(const float hour); float getWindSpeed() const; @@ -195,6 +202,7 @@ namespace MWWorld float calculateAngleFade (const std::string& moonName, float angle) const; void setWeather(Weather::Type weatherType, bool instant=false); + Weather::Type nextWeather(const ESM::Region* region); WeatherResult mResult; float mSunriseTime; float mSunsetTime; From f9940413fd611a2976e82be6e1413e3e484c5921 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Wed, 19 Jun 2013 16:49:43 +0200 Subject: [PATCH 160/213] Static for nextWeather() --- apps/openmw/mwworld/weather.cpp | 2 +- apps/openmw/mwworld/weather.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 89c5892a9..2d63dd6d5 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -579,7 +579,7 @@ void WeatherManager::stopSounds(bool stopAll) } } -Weather::Type WeatherManager::nextWeather(const ESM::Region* region) +Weather::Type WeatherManager::nextWeather(const ESM::Region* region) const { /* * All probabilities must add to 100 (responsibility of the user). diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index fa305dc3c..90b0a2dc5 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -202,7 +202,7 @@ namespace MWWorld float calculateAngleFade (const std::string& moonName, float angle) const; void setWeather(Weather::Type weatherType, bool instant=false); - Weather::Type nextWeather(const ESM::Region* region); + Weather::Type nextWeather(const ESM::Region* region) const; WeatherResult mResult; float mSunriseTime; float mSunsetTime; From 26a6bdb27dfec80bb71b3069d2acfda281e38d61 Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Wed, 19 Jun 2013 19:37:35 +0200 Subject: [PATCH 161/213] Correction of sigsegv. --- apps/openmw/mwworld/weather.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 2d63dd6d5..4a2a2f803 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -118,9 +118,9 @@ float WeatherManager::calculateAngleFade (const std::string& moonName, float ang } WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fallback* fallback) : - mHour(14), mCurrentWeather(Weather::Type_Clear), mFirstUpdate(true), mWeatherUpdateTime(0), - mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), - mRemainingTransitionTime(0), mMonth(0), mDay(0), + mHour(14), mCurrentWeather(Weather::Type_Clear), mNextWeather(Weather::Type_Unknown), + mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), + mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0), mMonth(0), mDay(0), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mRendering(rendering) { //Globals @@ -545,14 +545,14 @@ void WeatherManager::update(float duration) if (mNextWeather == Weather::Type_Unknown) { std::string ambientSnd = mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID; - if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end()) + if (!ambientSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end()) { mSoundsPlaying.push_back(ambientSnd); MWBase::Environment::get().getSoundManager()->playSound(ambientSnd, 1.0, 1.0, MWBase::SoundManager::Play_Loop); } std::string rainSnd = mWeatherSettings[mCurrentWeather].mRainLoopSoundID; - if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end()) + if (!rainSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end()) { mSoundsPlaying.push_back(rainSnd); MWBase::Environment::get().getSoundManager()->playSound(rainSnd, 1.0, 1.0, MWBase::SoundManager::Play_Loop); @@ -568,14 +568,14 @@ void WeatherManager::stopSounds(bool stopAll) while (it!=mSoundsPlaying.end()) { if (stopAll || \ - !(*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID || \ - *it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID)) + !((*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID) || \ + (*it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID))) { MWBase::Environment::get().getSoundManager()->stopSound(*it); it = mSoundsPlaying.erase(it); } - - ++it; + else + ++it; } } From 4f4b41d4fa48186fa1fba94aaa43334a479a21e8 Mon Sep 17 00:00:00 2001 From: Alex McKibben Date: Thu, 20 Jun 2013 00:06:15 -0400 Subject: [PATCH 162/213] added my real name where credited as podcaster --- credits.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/credits.txt b/credits.txt index 411625d09..1f7c94e7f 100644 --- a/credits.txt +++ b/credits.txt @@ -79,7 +79,7 @@ Julien Voisin (jvoisin/ap0) - French News Writer Mickey Lyle (raevol) - Release Manager Pithorn - Chinese News Writer sir_herrbatka - English/Polish News Writer -WeirdSexy - Podcaster +Alex McKibben (WeirdSexy) - Podcaster Website: From 8da3494d74c783574c850c691d3efcc7bb732cef Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Thu, 20 Jun 2013 21:44:28 +0200 Subject: [PATCH 163/213] Revert "Type of weather changed from string to enum." This reverts commit 04d90b4c47e140cec53750d523378d2cf9938387. Conflicts: apps/openmw/mwworld/weather.cpp apps/openmw/mwworld/weather.hpp --- apps/openmw/mwbase/world.hpp | 2 +- apps/openmw/mwworld/weather.cpp | 225 ++++++++++++++++++------------- apps/openmw/mwworld/weather.hpp | 36 ++--- apps/openmw/mwworld/worldimp.cpp | 2 +- apps/openmw/mwworld/worldimp.hpp | 2 +- 5 files changed, 144 insertions(+), 123 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 8a83aaf86..86a6a89d2 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -191,7 +191,7 @@ namespace MWBase virtual bool toggleSky() = 0; ///< \return Resulting mode - virtual void changeWeather(const std::string& region, int id) = 0; + virtual void changeWeather(const std::string& region, unsigned int id) = 0; virtual int getCurrentWeather() const = 0; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 4a2a2f803..68a46ec12 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -31,62 +31,35 @@ namespace } } -std::string Weather::weatherTypeToStr(Weather::Type type) +void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name) { - switch (type) { - case Type_Clear: - return "Clear"; - case Type_Cloudy: - return "Cloudy"; - case Type_Foggy: - return "Foggy"; - case Type_Overcast: - return "Overcast"; - case Type_Rain: - return "Rain"; - case Type_Thunderstorm: - return "Thunderstorm"; - case Type_Ashstorm: - return "Ashstorm"; - case Type_Blight: - return "Blight"; - case Type_Snow: - return "Snow"; - case Type_Blizzard: - return "Blizzard"; - default: // Type_Unknown - return ""; - } -} - -void WeatherManager::setFallbackWeather(Weather& weather, Weather::Type type) -{ - const std::string weatherName = Weather::weatherTypeToStr(type); - weather.mCloudsMaximumPercent = mFallback->getFallbackFloat("Weather_"+weatherName+"_Clouds_Maximum_Percent"); - weather.mTransitionDelta = mFallback->getFallbackFloat("Weather_"+weatherName+"_Transition_Delta"); - weather.mSkySunriseColor= mFallback->getFallbackColour("Weather_"+weatherName+"_Sky_Sunrise_Color"); - weather.mSkyDayColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sky_Day_Color"); - weather.mSkySunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sky_Sunset_Color"); - weather.mSkyNightColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sky_Night_Color"); - weather.mFogSunriseColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Fog_Sunrise_Color"); - weather.mFogDayColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Fog_Day_Color"); - weather.mFogSunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Fog_Sunset_Color"); - weather.mFogNightColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Fog_Night_Color"); - weather.mAmbientSunriseColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Ambient_Sunrise_Color"); - weather.mAmbientDayColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Ambient_Day_Color"); - weather.mAmbientSunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Ambient_Sunset_Color"); - weather.mAmbientNightColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Ambient_Night_Color"); - weather.mSunSunriseColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Sunrise_Color"); - weather.mSunDayColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Day_Color"); - weather.mSunSunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Sunset_Color"); - weather.mSunNightColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Night_Color"); - weather.mSunDiscSunsetColor = mFallback->getFallbackColour("Weather_"+weatherName+"_Sun_Disc_Sunset_Color"); - weather.mLandFogDayDepth = mFallback->getFallbackFloat("Weather_"+weatherName+"_Land_Fog_Day_Depth"); - weather.mLandFogNightDepth = mFallback->getFallbackFloat("Weather_"+weatherName+"_Land_Fog_Night_Depth"); - weather.mWindSpeed = mFallback->getFallbackFloat("Weather_"+weatherName+"_Wind_Speed"); - weather.mCloudSpeed = mFallback->getFallbackFloat("Weather_"+weatherName+"_Cloud_Speed"); - weather.mGlareView = mFallback->getFallbackFloat("Weather_"+weatherName+"_Glare_View"); - mWeatherSettings[type] = weather; + std::string upper=name; + upper[0]=toupper(name[0]); + weather.mCloudsMaximumPercent = mFallback->getFallbackFloat("Weather_"+upper+"_Clouds_Maximum_Percent"); + weather.mTransitionDelta = mFallback->getFallbackFloat("Weather_"+upper+"_Transition_Delta"); + weather.mSkySunriseColor=mFallback->getFallbackColour("Weather_"+upper+"_Sky_Sunrise_Color"); + weather.mSkyDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Day_Color"); + weather.mSkySunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Sunset_Color"); + weather.mSkyNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Sky_Night_Color"); + weather.mFogSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Sunrise_Color"); + weather.mFogDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Day_Color"); + weather.mFogSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Sunset_Color"); + weather.mFogNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Fog_Night_Color"); + weather.mAmbientSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Sunrise_Color"); + weather.mAmbientDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Day_Color"); + weather.mAmbientSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Sunset_Color"); + weather.mAmbientNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Ambient_Night_Color"); + weather.mSunSunriseColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Sunrise_Color"); + weather.mSunDayColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Day_Color"); + weather.mSunSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Sunset_Color"); + weather.mSunNightColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Night_Color"); + weather.mSunDiscSunsetColor = mFallback->getFallbackColour("Weather_"+upper+"_Sun_Disc_Sunset_Color"); + weather.mLandFogDayDepth = mFallback->getFallbackFloat("Weather_"+upper+"_Land_Fog_Day_Depth"); + weather.mLandFogNightDepth = mFallback->getFallbackFloat("Weather_"+upper+"_Land_Fog_Night_Depth"); + weather.mWindSpeed = mFallback->getFallbackFloat("Weather_"+upper+"_Wind_Speed"); + weather.mCloudSpeed = mFallback->getFallbackFloat("Weather_"+upper+"_Cloud_Speed"); + weather.mGlareView = mFallback->getFallbackFloat("Weather_"+upper+"_Glare_View"); + mWeatherSettings[name] = weather; } @@ -118,10 +91,11 @@ float WeatherManager::calculateAngleFade (const std::string& moonName, float ang } WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fallback* fallback) : - mHour(14), mCurrentWeather(Weather::Type_Clear), mNextWeather(Weather::Type_Unknown), - mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), - mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0), mMonth(0), mDay(0), - mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mRendering(rendering) + mHour(14), mCurrentWeather("clear"), mNextWeather(""), mFirstUpdate(true), + mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), + mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0), + mMonth(0), mDay(0), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), + mRendering(rendering) { //Globals mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0"); @@ -152,53 +126,53 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa //Weather Weather clear; clear.mCloudTexture = "tx_sky_clear.dds"; - setFallbackWeather(clear, Weather::Type_Clear); + setFallbackWeather(clear,"clear"); Weather cloudy; cloudy.mCloudTexture = "tx_sky_cloudy.dds"; - setFallbackWeather(cloudy, Weather::Type_Cloudy); + setFallbackWeather(cloudy,"cloudy"); Weather foggy; foggy.mCloudTexture = "tx_sky_foggy.dds"; - setFallbackWeather(foggy, Weather::Type_Foggy); + setFallbackWeather(foggy,"foggy"); Weather thunderstorm; thunderstorm.mCloudTexture = "tx_sky_thunder.dds"; thunderstorm.mRainLoopSoundID = "rain heavy"; - setFallbackWeather(thunderstorm, Weather::Type_Thunderstorm); + setFallbackWeather(thunderstorm,"thunderstorm"); Weather rain; rain.mCloudTexture = "tx_sky_rainy.dds"; rain.mRainLoopSoundID = "rain"; - setFallbackWeather(rain, Weather::Type_Rain); + setFallbackWeather(rain,"rain"); Weather overcast; overcast.mCloudTexture = "tx_sky_overcast.dds"; - setFallbackWeather(overcast, Weather::Type_Overcast); + setFallbackWeather(overcast,"overcast"); Weather ashstorm; ashstorm.mCloudTexture = "tx_sky_ashstorm.dds"; ashstorm.mAmbientLoopSoundID = "ashstorm"; - setFallbackWeather(ashstorm, Weather::Type_Ashstorm); + setFallbackWeather(ashstorm,"ashstorm"); Weather blight; blight.mCloudTexture = "tx_sky_blight.dds"; blight.mAmbientLoopSoundID = "blight"; - setFallbackWeather(blight, Weather::Type_Blight); + setFallbackWeather(blight,"blight"); Weather snow; snow.mCloudTexture = "tx_bm_sky_snow.dds"; - setFallbackWeather(snow, Weather::Type_Snow); + setFallbackWeather(snow, "snow"); Weather blizzard; blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds"; blizzard.mAmbientLoopSoundID = "BM Blizzard"; - setFallbackWeather(blizzard, Weather::Type_Blizzard); + setFallbackWeather(blizzard,"blizzard"); } -void WeatherManager::setWeather(Weather::Type weatherType, bool instant) +void WeatherManager::setWeather(const String& weather, bool instant) { - if (weatherType == mCurrentWeather && mNextWeather == Weather::Type_Unknown) + if (weather == mCurrentWeather && mNextWeather == "") { mFirstUpdate = false; return; @@ -206,25 +180,25 @@ void WeatherManager::setWeather(Weather::Type weatherType, bool instant) if (instant || mFirstUpdate) { - mNextWeather = Weather::Type_Unknown; - mCurrentWeather = weatherType; + mNextWeather = ""; + mCurrentWeather = weather; } else { - if (mNextWeather != Weather::Type_Unknown) + if (mNextWeather != "") { // transition more than 50% finished? if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600) <= 0.5) mCurrentWeather = mNextWeather; } - mNextWeather = weatherType; + mNextWeather = weather; mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600; } mFirstUpdate = false; } -void WeatherManager::setResult(Weather::Type weatherType) +void WeatherManager::setResult(const String& weatherType) { const Weather& current = mWeatherSettings[weatherType]; @@ -366,7 +340,7 @@ void WeatherManager::update(float duration) mCurrentRegion = regionstr; mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; - Weather::Type weatherType = Weather::Type_Clear; + std::string weatherType = "clear"; if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) weatherType = mRegionOverrides[regionstr]; @@ -385,17 +359,17 @@ void WeatherManager::update(float duration) setWeather(weatherType, false); } - if (mNextWeather != Weather::Type_Unknown) + if (mNextWeather != "") { mRemainingTransitionTime -= timePassed; if (mRemainingTransitionTime < 0) { mCurrentWeather = mNextWeather; - mNextWeather = Weather::Type_Unknown; + mNextWeather = ""; } } - if (mNextWeather != Weather::Type_Unknown) + if (mNextWeather != "") transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600))); else setResult(mCurrentWeather); @@ -487,7 +461,7 @@ void WeatherManager::update(float duration) mRendering->getSkyManager()->secundaDisable(); } - if (mCurrentWeather == Weather::Type_Thunderstorm && mNextWeather == Weather::Type_Unknown) + if (mCurrentWeather == "thunderstorm" && mNextWeather == "") { if (mThunderFlash > 0) { @@ -542,7 +516,7 @@ void WeatherManager::update(float duration) // Play sounds - if (mNextWeather == Weather::Type_Unknown) + if (mNextWeather == "") { std::string ambientSnd = mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID; if (!ambientSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end()) @@ -579,7 +553,7 @@ void WeatherManager::stopSounds(bool stopAll) } } -Weather::Type WeatherManager::nextWeather(const ESM::Region* region) const +Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const { /* * All probabilities must add to 100 (responsibility of the user). @@ -602,16 +576,36 @@ Weather::Type WeatherManager::nextWeather(const ESM::Region* region) const int chance = (rand() % 100) + 1; // 1..100 int sum = 0; - int i = 0; - for (; i < 10; ++i) + for (int i = 0; i < 10; ++i) { sum += probability[i]; if (chance < sum) { - break; + switch (i) + { + case 1: + return "cloudy"; + case 2: + return "foggy"; + case 3: + return "overcast"; + case 4: + return "rain"; + case 5: + return "thunderstorm"; + case 6: + return "ashstorm"; + case 7: + return "blight"; + case 8: + return "snow"; + case 9: + return "blizzard"; + default: // case 0 + return "clear"; + } } } - return (Weather::Type) i; } void WeatherManager::setHour(const float hour) @@ -628,23 +622,66 @@ void WeatherManager::setDate(const int day, const int month) unsigned int WeatherManager::getWeatherID() const { // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather - return mCurrentWeather; + + if (mCurrentWeather == "clear") + return 0; + else if (mCurrentWeather == "cloudy") + return 1; + else if (mCurrentWeather == "foggy") + return 2; + else if (mCurrentWeather == "overcast") + return 3; + else if (mCurrentWeather == "rain") + return 4; + else if (mCurrentWeather == "thunderstorm") + return 5; + else if (mCurrentWeather == "ashstorm") + return 6; + else if (mCurrentWeather == "blight") + return 7; + else if (mCurrentWeather == "snow") + return 8; + else if (mCurrentWeather == "blizzard") + return 9; + + else + return 0; } -void WeatherManager::changeWeather(const std::string& region, const int id) +void WeatherManager::changeWeather(const std::string& region, const unsigned int id) { // make sure this region exists MWBase::Environment::get().getWorld()->getStore().get().find(region); - Weather::Type weatherType = Weather::Type_Clear; - if (id >= Weather::Type_Clear && id < Weather::Type_Unknown) - weatherType = (Weather::Type)id; + std::string weather; + if (id==0) + weather = "clear"; + else if (id==1) + weather = "cloudy"; + else if (id==2) + weather = "foggy"; + else if (id==3) + weather = "overcast"; + else if (id==4) + weather = "rain"; + else if (id==5) + weather = "thunderstorm"; + else if (id==6) + weather = "ashstorm"; + else if (id==7) + weather = "blight"; + else if (id==8) + weather = "snow"; + else if (id==9) + weather = "blizzard"; + else + weather = "clear"; - mRegionOverrides[Misc::StringUtils::lowerCase(region)] = weatherType; + mRegionOverrides[Misc::StringUtils::lowerCase(region)] = weather; std::string playerRegion = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion; if (Misc::StringUtils::ciEqual(region, playerRegion)) - setWeather(weatherType); + setWeather(weather); } float WeatherManager::getWindSpeed() const diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 90b0a2dc5..1a787aae8 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -55,21 +55,6 @@ namespace MWWorld /// Defines a single weather setting (according to INI) struct Weather { - enum Type - { - Type_Clear = 0, - Type_Cloudy, - Type_Foggy, - Type_Overcast, - Type_Rain, - Type_Thunderstorm, - Type_Ashstorm, - Type_Blight, - Type_Snow, - Type_Blizzard, - Type_Unknown - }; - Ogre::String mCloudTexture; // Sky (atmosphere) colors @@ -126,8 +111,6 @@ namespace MWWorld Ogre::String mRainLoopSoundID; /// \todo disease chance - - static std::string weatherTypeToStr(Weather::Type type); }; /// @@ -143,7 +126,7 @@ namespace MWWorld * @param region that should be changed * @param ID of the weather setting to shift to */ - void changeWeather(const std::string& region, const int id); + void changeWeather(const std::string& region, const unsigned int id); /** * Per-frame update @@ -171,17 +154,17 @@ namespace MWWorld int mDay, mMonth; float mWindSpeed; MWWorld::Fallback* mFallback; - void setFallbackWeather(Weather& weather, Weather::Type type); + void setFallbackWeather(Weather& weather,const std::string& name); MWRender::RenderingManager* mRendering; - std::map mWeatherSettings; + std::map mWeatherSettings; - std::map mRegionOverrides; + std::map mRegionOverrides; std::vector mSoundsPlaying; - Weather::Type mCurrentWeather; - Weather::Type mNextWeather; + Ogre::String mCurrentWeather; + Ogre::String mNextWeather; std::string mCurrentRegion; @@ -196,14 +179,15 @@ namespace MWWorld double mTimePassed; // time passed since last update void transition(const float factor); - void setResult(Weather::Type weatherType); + void setResult(const Ogre::String& weatherType); float calculateHourFade (const std::string& moonName) const; float calculateAngleFade (const std::string& moonName, float angle) const; - void setWeather(Weather::Type weatherType, bool instant=false); - Weather::Type nextWeather(const ESM::Region* region) const; + void setWeather(const Ogre::String& weatherType, bool instant=false); + Ogre::String nextWeather(const ESM::Region* region) const; WeatherResult mResult; + float mSunriseTime; float mSunsetTime; float mSunriseDuration; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index ee642f869..16cba2ea8 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1371,7 +1371,7 @@ namespace MWWorld return mWeatherManager->getWeatherID(); } - void World::changeWeather(const std::string& region, const int id) + void World::changeWeather(const std::string& region, const unsigned int id) { mWeatherManager->changeWeather(region, id); } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 35eba979f..12438efd4 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -225,7 +225,7 @@ namespace MWWorld virtual bool toggleSky(); ///< \return Resulting mode - virtual void changeWeather (const std::string& region, int id); + virtual void changeWeather (const std::string& region, unsigned int id); virtual int getCurrentWeather() const; From 101c1472173bf936beaf042500327e7672e628b4 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Thu, 20 Jun 2013 18:06:25 -0500 Subject: [PATCH 164/213] Final changes for record status icon feature, incl. window size user preference 1. Included updated status icons, added base.png 2. Added doxygen comments CSV / CSM Settings classes 3. Implemented Glorf's code for window size preference 4. Minor changes code that searches maps in CSV / CSM Settings classes 5. Removed CSVSettings::SamplePage class 6. Other minor code maintenance / improvements --- apps/opencs/CMakeLists.txt | 1 - apps/opencs/editor.cpp | 12 +- .../model/settings/settingcontainer.hpp | 16 ++- apps/opencs/model/settings/settingsitem.cpp | 15 +- apps/opencs/model/settings/settingsitem.hpp | 17 +++ apps/opencs/model/settings/usersettings.cpp | 78 ++--------- apps/opencs/model/settings/usersettings.hpp | 49 ++++--- apps/opencs/view/doc/view.cpp | 26 +++- apps/opencs/view/doc/view.hpp | 7 + apps/opencs/view/doc/viewmanager.cpp | 8 +- apps/opencs/view/doc/viewmanager.hpp | 1 + apps/opencs/view/settings/abstractblock.cpp | 12 +- apps/opencs/view/settings/abstractblock.hpp | 27 ++-- apps/opencs/view/settings/abstractpage.cpp | 11 +- apps/opencs/view/settings/abstractpage.hpp | 11 ++ apps/opencs/view/settings/abstractwidget.hpp | 23 ++-- apps/opencs/view/settings/blankpage.cpp | 7 +- apps/opencs/view/settings/blankpage.hpp | 5 +- apps/opencs/view/settings/customblock.cpp | 5 +- apps/opencs/view/settings/customblock.hpp | 11 ++ apps/opencs/view/settings/editorpage.cpp | 10 +- apps/opencs/view/settings/editorpage.hpp | 5 +- apps/opencs/view/settings/groupblock.cpp | 4 +- apps/opencs/view/settings/groupblock.hpp | 11 ++ apps/opencs/view/settings/groupbox.hpp | 1 + apps/opencs/view/settings/itemblock.hpp | 10 ++ apps/opencs/view/settings/proxyblock.cpp | 2 +- apps/opencs/view/settings/proxyblock.hpp | 14 +- apps/opencs/view/settings/samplepage.cpp | 10 +- apps/opencs/view/settings/settingwidget.hpp | 8 +- apps/opencs/view/settings/support.hpp | 129 +++++++++++++----- apps/opencs/view/settings/toggleblock.hpp | 2 + .../view/settings/usersettingsdialog.cpp | 85 ++---------- .../view/settings/usersettingsdialog.hpp | 22 ++- apps/opencs/view/settings/windowpage.cpp | 106 ++++++++------ apps/opencs/view/settings/windowpage.hpp | 6 + .../view/world/recordstatusdelegate.cpp | 2 + .../view/world/recordstatusdelegate.hpp | 1 + files/opencs/resources.qrc | 1 + 39 files changed, 420 insertions(+), 351 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 501958714..866c0f1f2 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -78,7 +78,6 @@ opencs_units (view/settings proxyblock abstractwidget usersettingsdialog - samplepage editorpage windowpage ) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 991d59537..082fa376c 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -62,15 +62,9 @@ void CS::Editor::setupDataFiles() mFileDialog.addFiles(path); } - //Settings setup - QStringList settingFiles; - QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); - - settingFiles.append(QString("opencs.cfg")); - settingFiles.append(userPath + QString("opencs.cfg")); - - mUserSettings.setSettingsFiles(settingFiles); - mUserSettings.readSettings(); + //load the settings into the userSettings instance. + const QString settingFileName = "opencs.cfg"; + CSMSettings::UserSettings::instance().loadSettings(settingFileName); } diff --git a/apps/opencs/model/settings/settingcontainer.hpp b/apps/opencs/model/settings/settingcontainer.hpp index 60f4eecad..5af298a57 100644 --- a/apps/opencs/model/settings/settingcontainer.hpp +++ b/apps/opencs/model/settings/settingcontainer.hpp @@ -15,19 +15,31 @@ namespace CSMSettings QStringList *mValues; public: + explicit SettingContainer (QObject *parent = 0); explicit SettingContainer (const QString &value, QObject *parent = 0); + /// add a value to the container + /// multiple values supported void insert (const QString &value); + + /// update an existing value + /// index specifies multiple values void update (const QString &value, int index = 0); + /// return value at specified index QString getValue (int index = -1) const; + + /// retrieve list of all values inline QStringList *getValues() const { return mValues; } + + /// return size of list int count() const; - //test for empty container - //useful for default-constructed containers returned by QMap when invalid key is passed + /// test for empty container + /// useful for default-constructed containers returned by QMap when invalid key is passed inline bool isEmpty() const { return (!mValue && !mValues); } + inline bool isMultiValue() const { return (mValues); } }; } diff --git a/apps/opencs/model/settings/settingsitem.cpp b/apps/opencs/model/settings/settingsitem.cpp index fef9d3e2f..2e6172cb8 100644 --- a/apps/opencs/model/settings/settingsitem.cpp +++ b/apps/opencs/model/settings/settingsitem.cpp @@ -66,21 +66,10 @@ bool CSMSettings::SettingsItem::updateItem(int valueListIndex) bool CSMSettings::SettingsItem::validate (const QString &value) { - bool isValid = true; - //validation required only if a value list or min/max value pair has been provided - if (mValueList->size()>0) - { - for (QStringList::ConstIterator it = mValueList->begin(); it !=mValueList->end(); ++it) - { - isValid = ( value == *it); - - if (isValid) - break; - } - } + bool isValid = (mValueList->find(value) != mValueList->end()); - else if (mValuePair) + if (!isValid && mValuePair) { int numVal = value.toInt(); diff --git a/apps/opencs/model/settings/settingsitem.hpp b/apps/opencs/model/settings/settingsitem.hpp index 9c5ed02af..4139b8545 100644 --- a/apps/opencs/model/settings/settingsitem.hpp +++ b/apps/opencs/model/settings/settingsitem.hpp @@ -7,6 +7,8 @@ namespace CSMSettings { + /// Represents a setting including metadata + /// (valid values, ranges, defaults, and multivalue status class SettingsItem : public SettingContainer { QStringPair *mValuePair; @@ -24,14 +26,24 @@ namespace CSMSettings QObject::setObjectName(name); } + /// updateItem overloads for updating setting value + /// provided a list of values (multi-valued), + /// a specific value + /// or an index value corresponding to the mValueList bool updateItem (const QStringList *values); bool updateItem (const QString &value); bool updateItem (int valueListIndex); + /// retroeve list of valid values for setting inline QStringList *getValueList() { return mValueList; } + + /// write list of valid values for setting inline void setValueList (QStringList *valueList) { mValueList = valueList; } + /// valuePair used for spin boxes (max / min) inline QStringPair *getValuePair() { return mValuePair; } + + /// set value range (spinbox / integer use) inline void setValuePair (QStringPair valuePair) { mValuePair = new QStringPair(valuePair); } inline bool isMultivalue () { return mIsMultiValue; } @@ -40,6 +52,11 @@ namespace CSMSettings QString getDefaultValue () const; private: + + /// Verifies that the supplied value is one of the following: + /// 1. Within the limits of the value pair (min / max) + /// 2. One of the values indicated in the value list + /// TODO: value list logic iterates QList. Should use find() instead. bool validate (const QString &value); }; } diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index ecdfcd71b..5bd2343cd 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -54,15 +54,7 @@ CSMSettings::UserSettings::~UserSettings() mUserSettingsInstance = 0; } - -//QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, bool isReadOnly) - -CSMSettings::SectionMap CSMSettings::UserSettings::getSettingsMap() const -{ - return mSectionMap; -} - -QFile *CSMSettings::UserSettings::openFile (const QString &filename) const +QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, bool isReadOnly) const { QFile *file = new QFile(filePath); @@ -105,10 +97,7 @@ QFile *CSMSettings::UserSettings::openFile (const QString &filename) const } -bool CSMSettings::UserSettings::writeFile(QMap &settings) - -//bool CSMSettings::UserSettings::writeFile(QFile *file, QMap &settings) const - +bool CSMSettings::UserSettings::writeSettings(QMap &settings) { QTextStream *stream = openFileStream(mPaths.back()); @@ -130,10 +119,7 @@ bool CSMSettings::UserSettings::writeFile(QMapobjectName(), setting->getValue()); - } -} - -void CSMSettings::UserSettings::readSettings() -{ - CSMSettings::SectionMap sectionMap; - - foreach (const QString &path, mSettingsFiles) - { - qDebug() << "Loading config file:" << qPrintable(path); - QFile file(path); - - if (file.exists()) + if (settings->find(settingName)!=settings->end()) { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error opening OpenCS configuration file")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(QObject::tr("
Could not open %0 for reading

\ - Please make sure you have the right permissions \ - and try again.
").arg(file.fileName())); - msgBox.exec(); - return; - } - - QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-8")); - - - getSettings(stream, mSectionMap); + setting = settings->value(settingName); + emit signalUpdateEditorSetting (setting->objectName(), setting->getValue()); } - - file.close(); } } -void CSMSettings::UserSettings::setSettingsFiles(QStringList files) -{ - mSettingsFiles = files; -} - -QStringList CSMSettings::UserSettings::getSettingsFiles () const -{ - return mSettingsFiles; -} - -QString CSMSettings::UserSettings::getSettingValue(QString section, QString setting) const +QString CSMSettings::UserSettings::getSetting (const QString §ion, const QString &setting) const { - if(mSectionMap.find(section) == mSectionMap.end()) + if(mSectionSettings.find(section) == mSectionSettings.end()) return QString(); - CSMSettings::SettingMap *settings = mSectionMap.value(section); + CSMSettings::SettingMap *settings = mSectionSettings.value(section); if(settings->find(setting) == settings->end()) return QString(); @@ -301,7 +243,7 @@ QString CSMSettings::UserSettings::getSettingValue(QString section, QString sett return settingContainer->getValue(); } -const CSMSettings::UserSettings& CSMSettings::UserSettings::instance() +CSMSettings::UserSettings& CSMSettings::UserSettings::instance() { assert(mUserSettingsInstance); return *mUserSettingsInstance; diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index f5eb5e80d..213c5a35c 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -27,56 +27,53 @@ namespace CSMSettings { Q_OBJECT SectionMap mSectionSettings; - UserSettings *mUserSettingsInstance; + static UserSettings *mUserSettingsInstance; QStringList mPaths; Files::ConfigurationManager mCfgMgr; - QString mReadOnlyMessage; QString mReadWriteMessage; public: + /// Singleton implementation + static UserSettings& instance(); + UserSettings(); ~UserSettings(); - static const UserSettings& instance(); + UserSettings (UserSettings const &); //not implemented + void operator= (UserSettings const &); //not implemented - void readSettings(); - void setSettingsFiles(QStringList files); + /// Writes settings to the last loaded settings file + bool writeSettings(QMap §ions); -<<<<<<< HEAD - bool writeFile(QMap §ions); - const SectionMap &getSettings (); + /// Called from editor to trigger signal to update the specified setting. + /// If no setting name is specified, all settings found in the specified section are updated. void updateSettings (const QString §ionName, const QString &settingName = ""); + + /// Retrieves the settings file at all three levels (global, local and user). + + /// TODO: Multi-valued settings are not fully implemented. Setting values + /// loaded in later files will always overwrite previously loaded values. void loadSettings (const QString &fileName); - private: + /// Returns the entire map of settings across all sections + const SectionMap &getSettings () const; - UserSettings(); - ~UserSettings(); -======= - QFile *openFile (const QString &) const; - bool writeFile(QFile *file, QMap §ions) const; - void getSettings (QTextStream &stream, SectionMap &settings) const; - QStringList getSettingsFiles () const; - CSMSettings::SectionMap getSettingsMap() const; - QString getSettingValue(QString section, QString setting) const; + /// Retrieves the value as a QString of the specified setting in the specified section + QString getSetting(const QString §ion, const QString &setting) const; private: - static UserSettings *mUserSettingsInstance; - CSMSettings::SectionMap mSectionMap; - QStringList mSettingsFiles; ->>>>>>> df1f1bd5c81d94a1ea2693000ec5dc589b069826 + /// Opens a QTextStream from the provided path as read-only or read-write. + QTextStream *openFileStream (const QString &filePath, bool isReadOnly = false) const; - UserSettings (UserSettings const &); //not implemented - void operator= (UserSettings const &); //not implemented - - QTextStream *openFileStream (const QString &filePath, bool isReadOnly = false); + /// Parses a setting file specified in filePath from the provided text stream. void loadFromFile (const QString &filePath = ""); signals: + void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue); }; diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 7e5a14c9c..ad88467df 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -180,8 +180,9 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews) { - QString width = CSMSettings::UserSettings::instance().getSettingValue(QString("Window Size"), QString("Width")); - QString height = CSMSettings::UserSettings::instance().getSettingValue(QString("Window Size"), QString("Height")); + QString width = CSMSettings::UserSettings::instance().getSetting(QString("Window Size"), QString("Width")); + QString height = CSMSettings::UserSettings::instance().getSetting(QString("Window Size"), QString("Height")); + if(width==QString() || height==QString()) resize(800, 600); else @@ -378,10 +379,31 @@ void CSVDoc::View::showUserSettings() settingsDialog->show(); } +void CSVDoc::View::resizeViewWidth (int width) +{ + if (width >= 0) + resize (width, geometry().height()); +} + +void CSVDoc::View::resizeViewHeight (int height) +{ + if (height >= 0) + resize (geometry().width(), height); +} + void CSVDoc::View::updateEditorSetting (const QString &settingName, const QString &settingValue) { if (settingName == "Record Status Display") + { foreach (QObject *view, mSubViewWindow.children()) + { if (view->objectName() == "subview") dynamic_cast(view)->updateEditorSetting (settingName, settingValue); + } + } + else if (settingName == "Width") + resizeViewWidth (settingValue.toInt()); + + else if (settingName == "Height") + resizeViewHeight (settingValue.toInt()); } diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 2fbe881eb..74504e308 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -70,6 +70,12 @@ namespace CSVDoc void loadUserSettings(); + /// User preference function + void resizeViewWidth (int width); + + /// User preference function + void resizeViewHeight (int height); + public: View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); @@ -90,6 +96,7 @@ namespace CSVDoc Operations *getOperations() const; + /// Function called by view manager when user preferences are updated void updateEditorSetting (const QString &, const QString &); signals: diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index a5ccc9efc..7e00697c3 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -21,6 +21,7 @@ #include #include +#include void CSVDoc::ViewManager::updateIndices() { std::map > documents; @@ -124,8 +125,6 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) connect (&CSMSettings::UserSettings::instance(), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)), this, SLOT (slotUpdateEditorSetting (const QString &, const QString &))); - - CSMSettings::UserSettings::instance().loadSettings("opencs.cfg"); } CSVDoc::ViewManager::~ViewManager() @@ -355,7 +354,10 @@ void CSVDoc::ViewManager::exitApplication (CSVDoc::View *view) void CSVDoc::ViewManager::slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) { - if (settingName == "Record Status Display") + if (settingName == "Record Status Display" || + settingName == "Width" || settingName == "Height") + { foreach (CSVDoc::View *view, mViews) view->updateEditorSetting (settingName, settingValue); + } } diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 2b0890a21..1f4dcd51b 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -73,6 +73,7 @@ namespace CSVDoc void onExitWarningHandler(int state, CSMDoc::Document* document); + /// connected to update signal in UserSettings void slotUpdateEditorSetting (const QString &, const QString &); }; diff --git a/apps/opencs/view/settings/abstractblock.cpp b/apps/opencs/view/settings/abstractblock.cpp index 72d360348..65825ce8b 100644 --- a/apps/opencs/view/settings/abstractblock.cpp +++ b/apps/opencs/view/settings/abstractblock.cpp @@ -38,27 +38,27 @@ CSVSettings::AbstractWidget *CSVSettings::AbstractBlock::buildWidget (const QStr { case Widget_RadioButton: - widg = createSettingWidget (def, layout); + widg = new SettingWidget (def, layout, mBox); break; case Widget_SpinBox: - widg = createSettingWidget (def, layout); + widg = new SettingWidget (def, layout, mBox); break; case Widget_CheckBox: - widg = createSettingWidget (def, layout); + widg = new SettingWidget (def, layout, mBox); break; case Widget_LineEdit: - widg = createSettingWidget (def, layout); + widg = new SettingWidget (def, layout, mBox); break; case Widget_ListBox: - widg = createSettingWidget (def, layout); + widg = new SettingWidget (def, layout, mBox); break; case Widget_ComboBox: - widg = createSettingWidget (def, layout); + widg = new SettingWidget (def, layout, mBox); break; default: diff --git a/apps/opencs/view/settings/abstractblock.hpp b/apps/opencs/view/settings/abstractblock.hpp index 42e00b6d7..36108d752 100644 --- a/apps/opencs/view/settings/abstractblock.hpp +++ b/apps/opencs/view/settings/abstractblock.hpp @@ -11,6 +11,7 @@ namespace CSVSettings { + /// Abstract base class for all blocks class AbstractBlock : public QObject { Q_OBJECT @@ -31,40 +32,50 @@ namespace CSVSettings bool isVisible() const; virtual CSMSettings::SettingList *getSettings() = 0; + + /// update settings found in the passed map and are encapsulated by the block virtual bool updateSettings (const CSMSettings::SettingMap &settings) = 0; + + /// update callback function called from update slot + /// used for updating application-level settings in the editor virtual bool updateBySignal (const QString &name, const QString &value, bool &doEmit) { return false; } protected: + /// Creates the layout which for the blocks QGroupBox QLayout *createLayout (Orientation direction, bool isZeroMargin, QWidget* parent = 0); + + /// Creates widgets that exist as direct children of the block AbstractWidget *buildWidget (const QString &widgetName, WidgetDef &wDef, QLayout *layout = 0, bool isConnected = true) const; - template - AbstractWidget *createSettingWidget (WidgetDef &wDef, QLayout *layout) const - { - return new SettingWidget (wDef, layout, mBox); - } - QWidget *getParent() const; public slots: + /// enables / disables block-level widgets based on signals from other widgets + /// used in ToggleBlock void slotSetEnabled (bool value); + + /// receives updates to applicaion-level settings in the Editor void slotUpdateSetting (const QString &settingName, const QString &settingValue); private slots: + /// receives updates to a setting in the block pushed from the application level void slotUpdate (const QString &value); signals: - //signal to functions outside the settings tab widget + /// signal to UserSettings instance void signalUpdateSetting (const QString &propertyName, const QString &propertyValue); + + /// signal to widget for updating widget value void signalUpdateWidget (const QString & value); - //propertyName and propertyValue are for properties for which the updated setting acts as a proxy + /// ProxyBlock use only. + /// Name and value correspond to settings for which the block is a proxy. void signalUpdateProxySetting (const QString &propertyName, const QString &propertyValue); }; } diff --git a/apps/opencs/view/settings/abstractpage.cpp b/apps/opencs/view/settings/abstractpage.cpp index 6e34af63b..e6c605275 100644 --- a/apps/opencs/view/settings/abstractpage.cpp +++ b/apps/opencs/view/settings/abstractpage.cpp @@ -29,16 +29,7 @@ CSVSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent CSVSettings::AbstractPage::~AbstractPage() { } -/* -void CSVSettings::AbstractPage::setupUi() -{ - // Hacks to get the stylesheet look properly - #ifdef Q_OS_MAC - QPlastiqueStyle *style = new QPlastiqueStyle; - //profilesComboBox->setStyle(style); - #endif -} -*/ + CSMSettings::SettingList *CSVSettings::AbstractPage::getSettings() { CSMSettings::SettingList *settings = new CSMSettings::SettingList(); diff --git a/apps/opencs/view/settings/abstractpage.hpp b/apps/opencs/view/settings/abstractpage.hpp index 1665b59d2..77ef4524f 100644 --- a/apps/opencs/view/settings/abstractpage.hpp +++ b/apps/opencs/view/settings/abstractpage.hpp @@ -14,6 +14,11 @@ namespace CSVSettings { typedef QList AbstractBlockList; + /// Abstract base class for all setting pages in the dialog + + /// \todo Scripted implementation of settings should eliminate the need + /// \todo derive page classes. + /// \todo AbstractPage should be replaced with a general page construction class. class AbstractPage: public QWidget { @@ -30,14 +35,20 @@ namespace CSVSettings { virtual void setupUi() = 0; + /// triggers widgiet initialization at the page level. All widgets updated to + /// current setting values virtual void initializeWidgets (const CSMSettings::SettingMap &settings) = 0; + /// retrieve the list of settings local to the page. CSMSettings::SettingList *getSettings(); void setObjectName(); protected: + /// Create a block for the page. + /// Block is constructed using passed definition struct + /// Page level-layout is created and assigned template AbstractBlock *buildBlock (T *def) { diff --git a/apps/opencs/view/settings/abstractwidget.hpp b/apps/opencs/view/settings/abstractwidget.hpp index ef00993fc..325de2bd2 100644 --- a/apps/opencs/view/settings/abstractwidget.hpp +++ b/apps/opencs/view/settings/abstractwidget.hpp @@ -8,6 +8,7 @@ class QLayout; namespace CSVSettings { + /// Abstract base class for widgets which are used in user preferences dialog class AbstractWidget : public QObject { Q_OBJECT @@ -16,45 +17,49 @@ namespace CSVSettings public: + /// Passed layout is assigned the constructed widget. + /// if no layout is passed, one is created. explicit AbstractWidget (QLayout *layout = 0, QWidget* parent = 0) : QObject (parent), mLayout (layout) {} - //retrieve layout for insertion into itemblock + /// retrieve layout for insertion into itemblock QLayout *getLayout(); - //create the derived widget instance + /// create the derived widget instance void build (QWidget* widget, WidgetDef &def, bool noLabel = false); - //reference to the derived widget instance + /// reference to the derived widget instance virtual QWidget *widget() = 0; protected: - //called by inbound signal for type-specific widget udpates + /// Callback called by receiving slot for widget udpates virtual void updateWidget (const QString &value) = 0; - //converts user-defined enum to Qt equivalents + /// Converts user-defined enum to Qt equivalents QFlags getAlignment (Alignment flag); private: - //widget initialization utilities + /// Creates layout and assigns label and widget as appropriate void createLayout (Orientation direction, bool isZeroMargin); + + /// Creates label and widget according to passed definition void buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel); signals: - //outbound update + /// outbound update signal void signalUpdateItem (const QString &value); public slots: - //inbound updates + /// receives inbound updates void slotUpdateWidget (const QString &value); - //Outbound updates from derived widget signal + /// Overloads for outbound updates from derived widget signal void slotUpdateItem (const QString &value); void slotUpdateItem (bool value); void slotUpdateItem (int value); diff --git a/apps/opencs/view/settings/blankpage.cpp b/apps/opencs/view/settings/blankpage.cpp index bf9c3c86e..837a31bee 100644 --- a/apps/opencs/view/settings/blankpage.cpp +++ b/apps/opencs/view/settings/blankpage.cpp @@ -20,16 +20,11 @@ CSVSettings::BlankPage::BlankPage(QWidget *parent): AbstractPage("Blank", parent) { - initPage(); + } CSVSettings::BlankPage::BlankPage(const QString &title, QWidget *parent): AbstractPage(title, parent) -{ - initPage(); -} - -void CSVSettings::BlankPage::initPage() { // Hacks to get the stylesheet look properly #ifdef Q_OS_MAC diff --git a/apps/opencs/view/settings/blankpage.hpp b/apps/opencs/view/settings/blankpage.hpp index 648d373f3..07049fb71 100644 --- a/apps/opencs/view/settings/blankpage.hpp +++ b/apps/opencs/view/settings/blankpage.hpp @@ -10,6 +10,8 @@ namespace CSVSettings { class UserSettings; class AbstractBlock; + /// Derived page with no widgets + /// Reference use only. class BlankPage : public AbstractPage { @@ -20,9 +22,6 @@ namespace CSVSettings { void setupUi(); void initializeWidgets (const CSMSettings::SettingMap &settings); - - private: - void initPage(); }; } diff --git a/apps/opencs/view/settings/customblock.cpp b/apps/opencs/view/settings/customblock.cpp index 933abf423..a07ee5ac9 100644 --- a/apps/opencs/view/settings/customblock.cpp +++ b/apps/opencs/view/settings/customblock.cpp @@ -59,7 +59,7 @@ int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef *def) int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef *def, ProxyBlock *block) { - if (def->properties.size() != 1) + if (def->settingItems.size() != 1) return -1; int retVal = block->build(def); @@ -67,7 +67,8 @@ int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef *def, ProxyBlock *bl if (retVal != 0) return retVal; - foreach (QStringList *list, *(def->properties.at(0)->proxyList)) + // The first settingItem is the proxy setting, containing the list of settings bound to it. + foreach (QStringList *list, *(def->settingItems.at(0)->proxyList)) { QString proxiedBlockName = list->at(0); diff --git a/apps/opencs/view/settings/customblock.hpp b/apps/opencs/view/settings/customblock.hpp index f831a90ba..54c50f395 100644 --- a/apps/opencs/view/settings/customblock.hpp +++ b/apps/opencs/view/settings/customblock.hpp @@ -8,6 +8,8 @@ namespace CSVSettings class ProxyBlock; + /// Base class for customized user preference setting blocks + /// Special block classes should be derived from CustomBlock class CustomBlock : public AbstractBlock { @@ -19,17 +21,26 @@ namespace CSVSettings explicit CustomBlock (QWidget *parent = 0); + /// Update settings local to the block bool updateSettings (const CSMSettings::SettingMap &settings); + + /// Retrieve settings local to the block CSMSettings::SettingList *getSettings(); + + /// construct the block using the passed definition int build (GroupBlockDefList &defList, GroupBlockDefList::Iterator *it = 0); protected: + /// construct the block groupbox GroupBox *buildGroupBox (Orientation orientation); private: + /// Construction function for creating a standard GroupBlock child int buildGroupBlock(GroupBlockDef *def); + + /// Construction function for creating a standard ProxyBlock child int buildProxyBlock(GroupBlockDef *def, ProxyBlock *block); }; } diff --git a/apps/opencs/view/settings/editorpage.cpp b/apps/opencs/view/settings/editorpage.cpp index 7d67312e7..50b5a6536 100644 --- a/apps/opencs/view/settings/editorpage.cpp +++ b/apps/opencs/view/settings/editorpage.cpp @@ -3,13 +3,7 @@ #include "../../model/settings/usersettings.hpp" CSVSettings::EditorPage::EditorPage(QWidget* parent) : - AbstractPage(parent) -{ - setupUi(); -} - -CSVSettings::EditorPage::EditorPage (const QString &pageName, QWidget* parent) - : AbstractPage (pageName, parent) + AbstractPage("Editor", parent) { setupUi(); } @@ -26,7 +20,7 @@ CSVSettings::GroupBlockDef *CSVSettings::EditorPage::setupRecordStatusDisplay() statusItem->widget = statusWidget; - statusBlock->properties << statusItem; + statusBlock->settingItems << statusItem; return statusBlock; } diff --git a/apps/opencs/view/settings/editorpage.hpp b/apps/opencs/view/settings/editorpage.hpp index 09769bf49..85215edab 100644 --- a/apps/opencs/view/settings/editorpage.hpp +++ b/apps/opencs/view/settings/editorpage.hpp @@ -12,15 +12,18 @@ namespace CSVSettings public: explicit EditorPage(QWidget *parent = 0); - explicit EditorPage (const QString &pageName, QWidget* parent = 0); void initializeWidgets (const CSMSettings::SettingMap &settings); void setupUi(); private: + + /// User preference view of the record status delegate's icon / text setting GroupBlockDef *setupRecordStatusDisplay(); signals: + + /// Signals up for changes to editor application-level settings void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue); public slots: diff --git a/apps/opencs/view/settings/groupblock.cpp b/apps/opencs/view/settings/groupblock.cpp index f23a4ae28..85720ad41 100644 --- a/apps/opencs/view/settings/groupblock.cpp +++ b/apps/opencs/view/settings/groupblock.cpp @@ -12,7 +12,7 @@ CSVSettings::GroupBlock::GroupBlock (bool isVisible, QWidget *parent) int CSVSettings::GroupBlock::build (GroupBlockDef *def) { - if (def->properties.size() == 0) + if (def->settingItems.size() == 0) return -1; int retVal = 0; @@ -24,7 +24,7 @@ int CSVSettings::GroupBlock::build (GroupBlockDef *def) setObjectName (def->title); mBox->setTitle (def->title); - foreach (SettingsItemDef *itemDef, def->properties) + foreach (SettingsItemDef *itemDef, def->settingItems) { ItemBlock *block = new ItemBlock (mBox); diff --git a/apps/opencs/view/settings/groupblock.hpp b/apps/opencs/view/settings/groupblock.hpp index bd16d0b5b..5c0754193 100644 --- a/apps/opencs/view/settings/groupblock.hpp +++ b/apps/opencs/view/settings/groupblock.hpp @@ -8,6 +8,8 @@ namespace CSVSettings { class ItemBlock; + /// Base class for group blocks. + /// Derived block classes should use CustomBlock class GroupBlock : public AbstractBlock { ItemBlockList mItemBlockList; @@ -16,15 +18,24 @@ namespace CSVSettings GroupBlock (QWidget* parent = 0); GroupBlock (bool isVisible, QWidget *parent = 0); + /// build the gorup block based on passed definition int build (GroupBlockDef *def); + /// update settings local to the group block bool updateSettings (const CSMSettings::SettingMap &settings); + /// retrieve setting list local to the group block CSMSettings::SettingList *getSettings(); + + /// retrieve item block by name from the passed list or local list ItemBlock *getItemBlock (const QString &name, ItemBlockList *blockList = 0); + + /// retrieve the item block by index from the local list ItemBlock *getItemBlock (int index); protected: + + /// create block layout based on passed definition int buildLayout (GroupBlockDef &def); }; diff --git a/apps/opencs/view/settings/groupbox.hpp b/apps/opencs/view/settings/groupbox.hpp index 43cb2e0c3..9d3a01936 100644 --- a/apps/opencs/view/settings/groupbox.hpp +++ b/apps/opencs/view/settings/groupbox.hpp @@ -5,6 +5,7 @@ namespace CSVSettings { + /// Custom implementation of QGroupBox to be used with block classes class GroupBox : public QGroupBox { static const QString INVISIBLE_BOX_STYLE; diff --git a/apps/opencs/view/settings/itemblock.hpp b/apps/opencs/view/settings/itemblock.hpp index c7714ac64..1a5447e31 100644 --- a/apps/opencs/view/settings/itemblock.hpp +++ b/apps/opencs/view/settings/itemblock.hpp @@ -15,22 +15,32 @@ namespace CSVSettings ItemBlock (QWidget* parent = 0); + /// pure virtual function not implemneted bool updateSettings (const CSMSettings::SettingMap &settings) { return false; } CSMSettings::SettingList *getSettings (); + QString getValue () const; + /// item blocks encapsulate only one setting int getSettingCount(); + + /// update setting value and corresponding widget bool update (const QString &value); + /// virtual construction function int build(SettingsItemDef &iDef); private: + /// custom construction function void buildItemBlock (SettingsItemDef& iDef); void buildItemBlockWidgets (SettingsItemDef& iDef); + + /// update the setting value bool updateItem (const QString &); + /// callback function triggered when update to application level is signalled bool updateBySignal (const QString &name, const QString &value, bool &doEmit); }; } diff --git a/apps/opencs/view/settings/proxyblock.cpp b/apps/opencs/view/settings/proxyblock.cpp index f47c9dd07..e13934fc0 100644 --- a/apps/opencs/view/settings/proxyblock.cpp +++ b/apps/opencs/view/settings/proxyblock.cpp @@ -8,7 +8,7 @@ CSVSettings::ProxyBlock::ProxyBlock (QWidget *parent) int CSVSettings::ProxyBlock::build (GroupBlockDef *proxyDef) { //get the list of pre-defined values for the proxy - mValueList = proxyDef->properties.at(0)->valueList; + mValueList = proxyDef->settingItems.at(0)->valueList; bool success = GroupBlock::build(proxyDef); diff --git a/apps/opencs/view/settings/proxyblock.hpp b/apps/opencs/view/settings/proxyblock.hpp index 73d31fecf..90fb9bc97 100644 --- a/apps/opencs/view/settings/proxyblock.hpp +++ b/apps/opencs/view/settings/proxyblock.hpp @@ -9,8 +9,7 @@ namespace CSVSettings { Q_OBJECT - //NOTE: mProxyItemBlockList and mProxyList - //should be combined into a value pair and stored in one list. + /// TODO: Combine mProxyItemBlockList and mProxyList. ItemBlockList mProxiedItemBlockList; ProxyList mProxyList; QStringList *mValueList; @@ -20,17 +19,28 @@ namespace CSVSettings explicit ProxyBlock (QWidget *parent = 0); explicit ProxyBlock (ItemBlock *proxyItemBlock, QWidget *parent = 0); + /// Add a block that contains a proxied setting to the proxy block. void addSetting (ItemBlock* settingBlock, QStringList *proxyList); + int build (GroupBlockDef *def); CSMSettings::SettingList *getSettings() { return 0; } + + /// Update settings local to the proxy block pushed from application level bool updateSettings (const CSMSettings::SettingMap &settings); + + /// callback function triggered when update to the application level is signaled. bool updateBySignal (const QString &name, const QString &value, bool &doEmit); private: + /// return the item block of a proxied setting ItemBlock *getProxiedItemBlock (const QString &name); + + /// update the proxy setting with data from the proxied settings bool updateByProxiedSettings(const CSMSettings::SettingMap *settings = 0); + + /// update proxied settings with data from the proxy setting bool updateProxiedSettings(); private slots: diff --git a/apps/opencs/view/settings/samplepage.cpp b/apps/opencs/view/settings/samplepage.cpp index 1ed2f0505..35a619390 100644 --- a/apps/opencs/view/settings/samplepage.cpp +++ b/apps/opencs/view/settings/samplepage.cpp @@ -44,7 +44,7 @@ void CSVSettings::SamplePage::setupUi() /////////////////////////// SettingsItemDef *undoStackItem = new SettingsItemDef (undoStack->title, "32"); - undoStack->properties << undoStackItem; + undoStack->settingItems << undoStackItem; undoStackItem->minMax.left = "0"; undoStackItem->minMax.right = "64"; @@ -59,7 +59,7 @@ void CSVSettings::SamplePage::setupUi() ///////////////////////////////////// SettingsItemDef *topLevelItem = new SettingsItemDef (topLevelWindowCount->title, "100"); - topLevelWindowCount->properties << topLevelItem; + topLevelWindowCount->settingItems << topLevelItem; topLevelItem->minMax.left = "1"; topLevelItem->minMax.right = "256"; @@ -80,7 +80,7 @@ void CSVSettings::SamplePage::setupUi() reuseSubWidget.valueList = (reuseSubItem->valueList); reuseSubWidget.widgetAlignment = Align_Left; - reuseSubwindow->properties << reuseSubItem; + reuseSubwindow->settingItems << reuseSubItem; reuseSubItem->widget = reuseSubWidget; /////////////////////////////// @@ -98,7 +98,7 @@ void CSVSettings::SamplePage::setupUi() heightItem->widget.widgetWidth = 45; heightItem->widget.caption = "x"; - customWindowSize->properties << widthItem << heightItem; + customWindowSize->settingItems << widthItem << heightItem; customWindowSize->widgetOrientation = Orient_Horizontal; customWindowSize->isVisible = false; @@ -119,7 +119,7 @@ void CSVSettings::SamplePage::setupUi() widthByHeightItem->widget = widthByHeightWidget; - definedWindowSize->properties << widthByHeightItem; + definedWindowSize->settingItems << widthByHeightItem; definedWindowSize->isProxy = true; definedWindowSize->isVisible = false; diff --git a/apps/opencs/view/settings/settingwidget.hpp b/apps/opencs/view/settings/settingwidget.hpp index b29523a3a..738b268b0 100644 --- a/apps/opencs/view/settings/settingwidget.hpp +++ b/apps/opencs/view/settings/settingwidget.hpp @@ -16,7 +16,8 @@ namespace CSVSettings { - //VALID FOR RADIOBUTTON / CHECKBOX (or other toggle widget with it's own label) + + /// Generic template for radiobuttons / checkboxes template class SettingWidget : public AbstractWidget { @@ -47,6 +48,7 @@ namespace CSVSettings } }; + /// spin box template template <> class SettingWidget : public AbstractWidget { @@ -90,6 +92,7 @@ namespace CSVSettings }; + /// combo box template template <> class SettingWidget : public CSVSettings::AbstractWidget { @@ -142,6 +145,7 @@ namespace CSVSettings }; + /// line edit template template <> class SettingWidget : public CSVSettings::AbstractWidget { @@ -175,6 +179,8 @@ namespace CSVSettings } }; + /// list widget template + /// TODO: Not fully implemented. Only widget supporting multi-valued settings template <> class SettingWidget : public CSVSettings::AbstractWidget { diff --git a/apps/opencs/view/settings/support.hpp b/apps/opencs/view/settings/support.hpp index 7185d2706..1df0dac1e 100644 --- a/apps/opencs/view/settings/support.hpp +++ b/apps/opencs/view/settings/support.hpp @@ -44,21 +44,44 @@ namespace CSVSettings Align_Right = Qt::AlignRight }; - //template for defining the widget of a property. + /// definition struct for widgets struct WidgetDef { - WidgetType type; //type of widget providing input - int labelWidth; //width of caption label - int widgetWidth; //width of input widget - Orientation orientation; //label / widget orientation (horizontal / vertical) - QString inputMask; //input mask (line edit) - QString caption; //label caption. Leave empty for multiple items. See BlockDef::captionList - QString value; //widget value. Leave empty for multiple items. See BlockDef::valueList - CSMSettings::QStringPair *minMax; //Min/Max QString value pair. If empty, assigned to property item value pair. - QStringList *valueList; //value list for list widgets. If left empty, is assigned to property item value list during block build(). - bool isDefault; //isDefault - determined at runtime. - Alignment valueAlignment; //left / center / right-justify text in widget - Alignment widgetAlignment; //left / center / right-justify widget in group box + /// type of widget providing input + WidgetType type; + + /// width of caption label + int labelWidth; + + /// width of input widget + int widgetWidth; + + /// label / widget orientation (horizontal / vertical) + Orientation orientation; + + /// input mask (line edit only) + QString inputMask; + + /// label caption. Leave empty for multiple items. See BlockDef::captionList + QString caption; + + /// widget value. Leave empty for multiple items. See BlockDef::valueList + QString value; + + /// Min/Max QString value pair. If empty, assigned to property item value pair. + CSMSettings::QStringPair *minMax; + + /// value list for list widgets. If left empty, is assigned to property item value list during block build(). + QStringList *valueList; + + /// determined at runtime + bool isDefault; + + /// left / center / right-justify text in widget + Alignment valueAlignment; + + /// left / center / right-justify widget in group box + Alignment widgetAlignment; WidgetDef() : labelWidth (-1), widgetWidth (-1), @@ -79,20 +102,34 @@ namespace CSVSettings }; - //Defines the attributes of the property as it is represented in the config file - //as well as the UI elements (group box and widget) that serve it. - //Only one widget may serve as the input widget for the property. + /// Defines the attributes of the setting as it is represented in the config file + /// as well as the UI elements (group box and widget) that serve it. + /// Only one widget may serve as the input widget for the setting. struct SettingsItemDef { - QString name; //property name - QStringList *valueList; //list of valid values for the property. - //Used to populate option widget captions or list widget item lists (see WidgetDef::caption / value) + /// setting name + QString name; + + /// list of valid values for the setting + QStringList *valueList; + + /// Used to populate option widget captions or list widget item lists (see WidgetDef::caption / value) QString defaultValue; + + /// flag indicating multi-valued setting bool hasMultipleValues; - CSMSettings::QStringPair minMax; //minimum / maximum value pair - WidgetDef widget; //definition of the input widget for this setting - Orientation orientation; //general orientation of the widget / label for this property - ProxyList *proxyList; //list of property and corresponding default values for proxy widget + + /// minimum / maximum value pair + CSMSettings::QStringPair minMax; + + /// definition of the input widget for this setting + WidgetDef widget; + + /// general orientation of the widget / label for this setting + Orientation orientation; + + /// list of settings and corresponding default values for proxy widget + ProxyList *proxyList; SettingsItemDef() : name (""), defaultValue (""), orientation (Orient_Vertical), hasMultipleValues (false) {} @@ -104,18 +141,32 @@ namespace CSVSettings }; - //Hierarchically, this is a "sub-section" of properties within a section, solely for UI organization. - //Does not correlate to config file structure. + /// Generic container block struct GroupBlockDef { - QString title; //title of the block containing the property or properties of this sub-section - QStringList captions; //list of captions for widgets at the block level (not associated with any particular property) - WidgetList widgets; //list of widgets at the block level (not associated with any particular property) - QList properties; //list of the property(ies) which are subordinate to the property block. - Orientation widgetOrientation; //general orientation of widgets in group block - bool isVisible; //determines whether or not box border/title are visible - bool isProxy; //indicates whether or not this block defines a proxy block - QString defaultValue; //generic default value attribute + /// block title + QString title; + + /// list of captions for widgets at the block level (not associated with any particular setting) + QStringList captions; + + /// list of widgets at the block level (not associated with any particular setting) + WidgetList widgets; + + /// list of the settings which are subordinate to the setting block. + QList settingItems; + + /// general orientation of widgets in group block + Orientation widgetOrientation; + + /// determines whether or not box border/title are visible + bool isVisible; + + /// indicates whether or not this block defines a proxy block + bool isProxy; + + /// generic default value attribute + QString defaultValue; GroupBlockDef (): title(""), widgetOrientation (Orient_Vertical), isVisible (true), isProxy (false), defaultValue ("") {} @@ -125,11 +176,19 @@ namespace CSVSettings {} }; + /// used to create unique, complex blocks struct CustomBlockDef { + /// block title QString title; - QString defaultValue; //default value for widgets unique to the custom block - GroupBlockDefList blockDefList; //list of settings groups that comprise the settings within the custom block + + /// default value for widgets unique to the custom block + QString defaultValue; + + /// list of settings groups that comprise the settings within the custom block + GroupBlockDefList blockDefList; + + /// orientation of the widgets within the block Orientation blockOrientation; CustomBlockDef (): title (""), defaultValue (""), blockOrientation (Orient_Horizontal) diff --git a/apps/opencs/view/settings/toggleblock.hpp b/apps/opencs/view/settings/toggleblock.hpp index db617e767..4b6e8e344 100644 --- a/apps/opencs/view/settings/toggleblock.hpp +++ b/apps/opencs/view/settings/toggleblock.hpp @@ -21,6 +21,8 @@ namespace CSVSettings int build (CustomBlockDef *def); private: + /// Constructor for toggle widgets that are specific to toggle block + /// Widgets are not a part of the user preference settings GroupBox *buildToggleWidgets (GroupBlockDef *def, QString &defaultToggle); }; } diff --git a/apps/opencs/view/settings/usersettingsdialog.cpp b/apps/opencs/view/settings/usersettingsdialog.cpp index ac1a5ead7..0f38bf560 100644 --- a/apps/opencs/view/settings/usersettingsdialog.cpp +++ b/apps/opencs/view/settings/usersettingsdialog.cpp @@ -9,19 +9,15 @@ #include #include #include -<<<<<<< HEAD + #include -#include "blankpage.hpp" #include "samplepage.hpp" -======= + #include -#include "blankpage.hpp" #include "editorpage.hpp" #include "windowpage.hpp" -#include "../../model/settings/support.hpp" ->>>>>>> df1f1bd5c81d94a1ea2693000ec5dc589b069826 #include "../../model/settings/support.hpp" #include @@ -32,12 +28,7 @@ CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) : { setWindowTitle(QString::fromUtf8 ("User Settings")); buildPages(); -<<<<<<< HEAD setWidgetStates (); -======= - setWidgetStates (CSMSettings::UserSettings::instance().getSettingsMap()); ->>>>>>> df1f1bd5c81d94a1ea2693000ec5dc589b069826 - positionWindow (); connect (mListWidget, SIGNAL (currentItemChanged(QListWidgetItem*, QListWidgetItem*)), @@ -63,11 +54,12 @@ void CSVSettings::UserSettingsDialog::setWidgetStates () for (int i = 0; i < mStackedWidget->count(); i++) { //get the settings defined for the entire section - CSMSettings::SettingMap *settings = sectionSettings [mStackedWidget->widget(i)->objectName()]; + //and update widget + QString pageName = mStackedWidget->widget(i)->objectName(); - //if found, initialize the page's widgets - if (settings) + if (sectionSettings.find(pageName) != sectionSettings.end()) { + CSMSettings::SettingMap *settings = sectionSettings.value(pageName); AbstractPage *page = getAbstractPage (i); page->initializeWidgets(*settings); } @@ -97,62 +89,11 @@ void CSVSettings::UserSettingsDialog::buildPages() setCentralWidget (centralWidget); setDockOptions (QMainWindow::AllowNestedDocks); - //uncomment to test with sample editor page. -<<<<<<< HEAD - // TODO: Reimplement sample page using createPage function - //createPage("Sample"); - createPage("Editor"); -======= - //createSamplePage(); - /*createPage("Page1"); ->>>>>>> df1f1bd5c81d94a1ea2693000ec5dc589b069826 - createPage("Page2"); - createPage("Page3");*/ - createWindowPage(); -} - -void CSVSettings::UserSettingsDialog::createSamplePage() -{ - //add pages to stackedwidget and items to listwidget - CSVSettings::AbstractPage *page - = new CSVSettings::SamplePage(this); - - mStackedWidget->addWidget (page); - - connect ( page, - SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)), - &(CSMSettings::UserSettings::instance()), - SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &))); + createPage(); + createPage(); - new QListWidgetItem (page->objectName(), mListWidget); } -void CSVSettings::UserSettingsDialog::createWindowPage() -{ - //add pages to stackedwidget and items to listwidget - CSVSettings::AbstractPage *page - = new CSVSettings::WindowPage(this); - - mStackedWidget->addWidget (page); - - new QListWidgetItem (page->objectName(), mListWidget); - - connect ( page, SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)), - &(CSMSettings::UserSettings::instance()), SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &))); -} - -<<<<<<< HEAD -======= -void CSVSettings::UserSettingsDialog::positionWindow () -{ - QRect scr = QApplication::desktop()->screenGeometry(); - - move(scr.center().x() - (width() / 2), scr.center().y() - (height() / 2)); - -} - - ->>>>>>> df1f1bd5c81d94a1ea2693000ec5dc589b069826 void CSVSettings::UserSettingsDialog::writeSettings() { QMap settings; @@ -162,15 +103,7 @@ void CSVSettings::UserSettingsDialog::writeSettings() AbstractPage *page = getAbstractPage (i); settings [page->objectName()] = page->getSettings(); } - -<<<<<<< HEAD - CSMSettings::UserSettings::instance().writeFile(settings); -======= - QStringList paths = CSMSettings::UserSettings::instance().getSettingsFiles(); - - CSMSettings::UserSettings::instance().writeFile(CSMSettings::UserSettings::instance().openFile(paths.back()), settings); ->>>>>>> df1f1bd5c81d94a1ea2693000ec5dc589b069826 - + CSMSettings::UserSettings::instance().writeSettings(settings); } CSVSettings::AbstractPage *CSVSettings::UserSettingsDialog::getAbstractPage (int index) diff --git a/apps/opencs/view/settings/usersettingsdialog.hpp b/apps/opencs/view/settings/usersettingsdialog.hpp index 620bf2f43..a992dbdf8 100644 --- a/apps/opencs/view/settings/usersettingsdialog.hpp +++ b/apps/opencs/view/settings/usersettingsdialog.hpp @@ -33,33 +33,27 @@ namespace CSVSettings { private: + /// Settings are written on close void closeEvent (QCloseEvent *event); + + /// return the setting page by name + /// performs dynamic cast to AbstractPage * AbstractPage *getAbstractPage (int index); void setWidgetStates (); void buildPages(); - void positionWindow (); void writeSettings(); - void createSamplePage(); - - //Pages - void createWindowPage(); + /// Templated function to create a custom user preference page template - void createPage (const QString &title) + void createPage () { - T *page = new T(title, this); + T *page = new T(mStackedWidget); mStackedWidget->addWidget (dynamic_cast(page)); new QListWidgetItem (page->objectName(), mListWidget); //finishing touches - if (mStackedWidget->sizeHint().width() < 640) - mStackedWidget->sizeHint().setWidth(640); - - if (mStackedWidget->sizeHint().height() < 480) - mStackedWidget->sizeHint().setHeight(480); - QFontMetrics fm (QApplication::font()); int textWidth = fm.width(page->objectName()); @@ -70,6 +64,8 @@ namespace CSVSettings { } public slots: + + /// Called when a different page is selected in the left-hand list widget void slotChangePage (QListWidgetItem*, QListWidgetItem*); }; diff --git a/apps/opencs/view/settings/windowpage.cpp b/apps/opencs/view/settings/windowpage.cpp index e8677fa42..fa7ee9b3e 100644 --- a/apps/opencs/view/settings/windowpage.cpp +++ b/apps/opencs/view/settings/windowpage.cpp @@ -16,6 +16,7 @@ #include "../../model/settings/usersettings.hpp" #include "groupblock.hpp" #include "toggleblock.hpp" +#include "../../view/settings/abstractblock.hpp" CSVSettings::WindowPage::WindowPage(QWidget *parent): AbstractPage("Window Size", parent) @@ -29,35 +30,10 @@ CSVSettings::WindowPage::WindowPage(QWidget *parent): setupUi(); } -void CSVSettings::WindowPage::setupUi() +CSVSettings::GroupBlockDef * CSVSettings::WindowPage::buildDefinedWindowSize() { - GroupBlockDef customWindowSize (QString ("Custom Window Size")); - GroupBlockDef definedWindowSize (QString ("Pre-Defined Window Size")); - GroupBlockDef windowSizeToggle (QString ("Window Size")); - CustomBlockDef windowSize (QString ("Window Size")); - - - /////////////////////////////// - //custom window size properties - /////////////////////////////// - - //custom width - SettingsItemDef *widthItem = new SettingsItemDef ("Width", "640"); - widthItem->widget = WidgetDef (Widget_LineEdit); - widthItem->widget.widgetWidth = 45; - - //custom height - SettingsItemDef *heightItem = new SettingsItemDef ("Height", "480"); - heightItem->widget = WidgetDef (Widget_LineEdit); - heightItem->widget.widgetWidth = 45; - heightItem->widget.caption = "x"; - - customWindowSize.properties << widthItem << heightItem; - customWindowSize.widgetOrientation = Orient_Horizontal; - customWindowSize.isVisible = false; + GroupBlockDef *block = new GroupBlockDef ( "Defined Size"); - - //pre-defined SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480"); WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox); widthByHeightWidget.widgetWidth = 90; @@ -73,27 +49,72 @@ void CSVSettings::WindowPage::setupUi() widthByHeightItem->widget = widthByHeightWidget; - definedWindowSize.properties << widthByHeightItem; - definedWindowSize.isProxy = true; - definedWindowSize.isVisible = false; + block->settingItems << widthByHeightItem; + block->isProxy = true; + block->isVisible = false; + + return block; +} + +CSVSettings::GroupBlockDef *CSVSettings::WindowPage::buildCustomWindowSize() +{ + GroupBlockDef *block = new GroupBlockDef ("Custom Size"); + + //custom width + SettingsItemDef *widthItem = new SettingsItemDef ("Width", "640"); + widthItem->widget = WidgetDef (Widget_LineEdit); + widthItem->widget.widgetWidth = 45; + + //custom height + SettingsItemDef *heightItem = new SettingsItemDef ("Height", "480"); + heightItem->widget = WidgetDef (Widget_LineEdit); + heightItem->widget.widgetWidth = 45; + heightItem->widget.caption = "x"; + + block->settingItems << widthItem << heightItem; + block->widgetOrientation = Orient_Horizontal; + block->isVisible = false; + + return block; +} + +CSVSettings::GroupBlockDef *CSVSettings::WindowPage::buildWindowSizeToggle() +{ + GroupBlockDef *block = new GroupBlockDef ("Window Size"); // window size toggle - windowSizeToggle.captions << "Pre-Defined" << "Custom"; - windowSizeToggle.widgetOrientation = Orient_Vertical; - windowSizeToggle.isVisible = false; + block->captions << "Pre-Defined" << "Custom"; + block->widgetOrientation = Orient_Vertical; + block->isVisible = false; //define a widget for each group in the toggle for (int i = 0; i < 2; i++) - windowSizeToggle.widgets << new WidgetDef (Widget_RadioButton); + block->widgets << new WidgetDef (Widget_RadioButton); - windowSizeToggle.widgets.at(0)->isDefault = false; + block->widgets.at(0)->isDefault = false; - windowSize.blockDefList << &windowSizeToggle << &definedWindowSize << &customWindowSize; - windowSize.defaultValue = "Custom"; + return block; +} + +CSVSettings::CustomBlockDef *CSVSettings::WindowPage::buildWindowSize(GroupBlockDef *toggle_def, + GroupBlockDef *defined_def, + GroupBlockDef *custom_def) +{ + CustomBlockDef *block = new CustomBlockDef(QString ("Window Size")); - QGridLayout *pageLayout = new QGridLayout(this); + block->blockDefList << toggle_def << defined_def << custom_def; + block->defaultValue = "Custom"; - setLayout (pageLayout); + return block; + +} + +void CSVSettings::WindowPage::setupUi() +{ + CustomBlockDef *windowSize = buildWindowSize(buildWindowSizeToggle(), + buildDefinedWindowSize(), + buildCustomWindowSize() + ); mAbstractBlocks << buildBlock (windowSize); @@ -102,8 +123,15 @@ void CSVSettings::WindowPage::setupUi() connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)), this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) ); } + + connect ( this, + SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)), + &(CSMSettings::UserSettings::instance()), + SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &))); + } + void CSVSettings::WindowPage::initializeWidgets (const CSMSettings::SettingMap &settings) { //iterate each item in each blocks in this section diff --git a/apps/opencs/view/settings/windowpage.hpp b/apps/opencs/view/settings/windowpage.hpp index 7978263fc..2f2830625 100644 --- a/apps/opencs/view/settings/windowpage.hpp +++ b/apps/opencs/view/settings/windowpage.hpp @@ -21,6 +21,12 @@ namespace CSVSettings { void setupUi(); void initializeWidgets (const CSMSettings::SettingMap &settings); + /// + GroupBlockDef *buildCustomWindowSize(); + GroupBlockDef *buildDefinedWindowSize(); + GroupBlockDef *buildWindowSizeToggle(); + CustomBlockDef *buildWindowSize (GroupBlockDef *, GroupBlockDef *, GroupBlockDef *); + signals: void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue); }; diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp index 3c61c4af4..243f509ef 100644 --- a/apps/opencs/view/world/recordstatusdelegate.cpp +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -10,6 +10,7 @@ CSVWorld::RecordStatusDelegate::RecordStatusDelegate(QUndoStack &undoStack, QObj mModifiedIcon = new QIcon (":./modified.png"); mAddedIcon = new QIcon (":./added.png"); mDeletedIcon = new QIcon (":./removed.png"); + mBaseIcon = new QIcon (":./base.png"); mIconSize = 16; //Offset values are most likely device-dependent. @@ -38,6 +39,7 @@ void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptio { case 0: // State_BaseOnly text = "Base"; + icon = mBaseIcon; break; case 1: // State_Modified diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp index 3f53f2f55..b67226ad5 100644 --- a/apps/opencs/view/world/recordstatusdelegate.hpp +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -21,6 +21,7 @@ namespace CSVWorld QIcon *mModifiedIcon; QIcon *mAddedIcon; QIcon *mDeletedIcon; + QIcon *mBaseIcon; int mStatusDisplay; diff --git a/files/opencs/resources.qrc b/files/opencs/resources.qrc index e2ad0ffd6..926bda064 100644 --- a/files/opencs/resources.qrc +++ b/files/opencs/resources.qrc @@ -4,5 +4,6 @@ added.png modified.png removed.png + base.png From f4a2cf64c2e2352f833dc2031bfd9820c43dfd7e Mon Sep 17 00:00:00 2001 From: graffy76 Date: Thu, 20 Jun 2013 18:07:34 -0500 Subject: [PATCH 165/213] Removed CSVSettings::SamplePage class files --- apps/opencs/view/settings/samplepage.cpp | 159 ----------------------- apps/opencs/view/settings/samplepage.hpp | 28 ---- 2 files changed, 187 deletions(-) delete mode 100644 apps/opencs/view/settings/samplepage.cpp delete mode 100644 apps/opencs/view/settings/samplepage.hpp diff --git a/apps/opencs/view/settings/samplepage.cpp b/apps/opencs/view/settings/samplepage.cpp deleted file mode 100644 index 35a619390..000000000 --- a/apps/opencs/view/settings/samplepage.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "samplepage.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef Q_OS_MAC -#include -#endif - -#include "../../model/settings/usersettings.hpp" -#include "groupblock.hpp" -#include "toggleblock.hpp" - -CSVSettings::SamplePage::SamplePage(QWidget *parent): - AbstractPage("Editor", parent) -{ - // Hacks to get the stylesheet look properly -#ifdef Q_OS_MAC - QPlastiqueStyle *style = new QPlastiqueStyle; - //profilesComboBox->setStyle(style); -#endif - - setupUi(); -} - -void CSVSettings::SamplePage::setupUi() -{ - GroupBlockDef *undoStack = new GroupBlockDef(QString("Undo Stack Size")); - GroupBlockDef *topLevelWindowCount = new GroupBlockDef(QString("Maximum Top-Level Window Count")); - GroupBlockDef *reuseSubwindow = new GroupBlockDef(QString("Reuse Subwindows")); - GroupBlockDef *customWindowSize = new GroupBlockDef(QString ("Custom Window Size")); - GroupBlockDef *definedWindowSize = new GroupBlockDef(QString ("Pre-Defined Window Size")); - GroupBlockDef *windowSizeToggle = new GroupBlockDef(QString ("Window Size")); - CustomBlockDef *windowSize = new CustomBlockDef(QString ("Window Size")); - - //////////////////////////// - //undo stack size property - /////////////////////////// - - SettingsItemDef *undoStackItem = new SettingsItemDef (undoStack->title, "32"); - undoStack->settingItems << undoStackItem; - undoStackItem->minMax.left = "0"; - undoStackItem->minMax.right = "64"; - - WidgetDef stackWidget (Widget_SpinBox); - stackWidget.minMax = &(undoStackItem->minMax); - stackWidget.widgetWidth = 50; - - undoStackItem->widget = stackWidget; - - ////////////////////////////////////// - //number of top level windows property - ///////////////////////////////////// - - SettingsItemDef *topLevelItem = new SettingsItemDef (topLevelWindowCount->title, "100"); - topLevelWindowCount->settingItems << topLevelItem; - topLevelItem->minMax.left = "1"; - topLevelItem->minMax.right = "256"; - - WidgetDef topLvlWinWidget (Widget_SpinBox); - topLvlWinWidget.minMax = &(topLevelItem->minMax); - topLvlWinWidget.widgetWidth = 50; - - topLevelItem->widget = topLvlWinWidget; - - /////////////////////////// - //reuse subwindows property - //////////////////////////// - - SettingsItemDef *reuseSubItem = new SettingsItemDef (reuseSubwindow->title, "Reuse Subwindows"); - *(reuseSubItem->valueList) << "None" << "Top-Level" << "Document-Level"; - - WidgetDef reuseSubWidget (Widget_RadioButton); - reuseSubWidget.valueList = (reuseSubItem->valueList); - reuseSubWidget.widgetAlignment = Align_Left; - - reuseSubwindow->settingItems << reuseSubItem; - reuseSubItem->widget = reuseSubWidget; - - /////////////////////////////// - //custom window size properties - /////////////////////////////// - - //custom width - SettingsItemDef *widthItem = new SettingsItemDef ("Window Width", "640"); - widthItem->widget = WidgetDef (Widget_LineEdit); - widthItem->widget.widgetWidth = 45; - - //custom height - SettingsItemDef *heightItem = new SettingsItemDef ("Window Height", "480"); - heightItem->widget = WidgetDef (Widget_LineEdit); - heightItem->widget.widgetWidth = 45; - heightItem->widget.caption = "x"; - - customWindowSize->settingItems << widthItem << heightItem; - customWindowSize->widgetOrientation = Orient_Horizontal; - customWindowSize->isVisible = false; - - - //pre-defined - SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480"); - WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox); - widthByHeightWidget.widgetWidth = 90; - *(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768"; - - QStringList *widthProxy = new QStringList; - QStringList *heightProxy = new QStringList; - - (*widthProxy) << "Window Width" << "640" << "800" << "1024"; - (*heightProxy) << "Window Height" << "480" << "600" << "768"; - - *(widthByHeightItem->proxyList) << widthProxy << heightProxy; - - widthByHeightItem->widget = widthByHeightWidget; - - definedWindowSize->settingItems << widthByHeightItem; - definedWindowSize->isProxy = true; - definedWindowSize->isVisible = false; - - // window size toggle - windowSizeToggle->captions << "Pre-Defined" << "Custom"; - windowSizeToggle->widgetOrientation = Orient_Vertical; - windowSizeToggle->isVisible = false; - - //define a widget for each group in the toggle - for (int i = 0; i < 2; i++) - windowSizeToggle->widgets << new WidgetDef (Widget_RadioButton); - - windowSizeToggle->widgets.at(0)->isDefault = false; - - windowSize->blockDefList << windowSizeToggle << definedWindowSize << customWindowSize; - windowSize->defaultValue = "Custom"; - - mAbstractBlocks << buildBlock (topLevelWindowCount) - << buildBlock (reuseSubwindow) - << buildBlock (windowSize) - << buildBlock (undoStack); - - foreach (AbstractBlock *block, mAbstractBlocks) - { - connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)), - this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) ); - } -} - -void CSVSettings::SamplePage::initializeWidgets (const CSMSettings::SettingMap &settings) -{ - //iterate each item in each blocks in this section - //validate the corresponding setting against the defined valuelist if any. - for (AbstractBlockList::Iterator it_block = mAbstractBlocks.begin(); - it_block != mAbstractBlocks.end(); ++it_block) - (*it_block)->updateSettings (settings); -} diff --git a/apps/opencs/view/settings/samplepage.hpp b/apps/opencs/view/settings/samplepage.hpp deleted file mode 100644 index 3a9448bad..000000000 --- a/apps/opencs/view/settings/samplepage.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SAMPLEPAGE_H -#define SAMPLEPAGE_H - -#include "abstractpage.hpp" - -class QGroupBox; - -namespace CSVSettings { - - class UserSettings; - class AbstractBlock; - - class SamplePage : public AbstractPage - { - Q_OBJECT - - public: - - explicit SamplePage(QWidget *parent = 0); - - void setupUi(); - void initializeWidgets (const CSMSettings::SettingMap &settings); - - signals: - void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue); - }; -} -#endif //SAMPLEPAGE_H From b3d185e4211d65eb7f70a8ca607ef85ab930aba7 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Thu, 20 Jun 2013 18:08:53 -0500 Subject: [PATCH 166/213] Unsaved changes missed in previous commits --- apps/opencs/model/settings/settingsitem.hpp | 1 - apps/opencs/model/settings/usersettings.hpp | 4 ++-- apps/opencs/view/settings/settingwidget.hpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/settings/settingsitem.hpp b/apps/opencs/model/settings/settingsitem.hpp index 4139b8545..c2587e892 100644 --- a/apps/opencs/model/settings/settingsitem.hpp +++ b/apps/opencs/model/settings/settingsitem.hpp @@ -56,7 +56,6 @@ namespace CSMSettings /// Verifies that the supplied value is one of the following: /// 1. Within the limits of the value pair (min / max) /// 2. One of the values indicated in the value list - /// TODO: value list logic iterates QList. Should use find() instead. bool validate (const QString &value); }; } diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index 213c5a35c..da8408b3e 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -53,8 +53,8 @@ namespace CSMSettings { /// Retrieves the settings file at all three levels (global, local and user). - /// TODO: Multi-valued settings are not fully implemented. Setting values - /// loaded in later files will always overwrite previously loaded values. + /// \todo Multi-valued settings are not fully implemented. Setting values + /// \todo loaded in later files will always overwrite previously loaded values. void loadSettings (const QString &fileName); /// Returns the entire map of settings across all sections diff --git a/apps/opencs/view/settings/settingwidget.hpp b/apps/opencs/view/settings/settingwidget.hpp index 738b268b0..9f4513671 100644 --- a/apps/opencs/view/settings/settingwidget.hpp +++ b/apps/opencs/view/settings/settingwidget.hpp @@ -180,7 +180,7 @@ namespace CSVSettings }; /// list widget template - /// TODO: Not fully implemented. Only widget supporting multi-valued settings + /// \todo Not fully implemented. Only widget supporting multi-valued settings template <> class SettingWidget : public CSVSettings::AbstractWidget { From 8b909ff838fd04d41edb48e10375ab847617b491 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 21 Jun 2013 08:58:52 +0200 Subject: [PATCH 167/213] killed a stray srand --- apps/openmw/mwworld/weather.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 68a46ec12..10dbdae9b 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -1,8 +1,5 @@ #include "weather.hpp" -#include -#include - #include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -210,7 +207,7 @@ void WeatherManager::setResult(const String& weatherType) mResult.mGlareView = current.mGlareView; mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID; mResult.mSunColor = current.mSunDiscSunsetColor; - + mResult.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1); mResult.mFogDepth = mResult.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth; @@ -485,7 +482,6 @@ void WeatherManager::update(float duration) mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold ); else { - srand(time(NULL)); mThunderChanceNeeded = rand() % 100; mThunderChance = 0; mRendering->getSkyManager()->setLightningStrength( 0.f ); From 75d7d3b7fce9ad0d368525993ff853dccadac6ea Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 21 Jun 2013 12:28:07 -0500 Subject: [PATCH 168/213] Added base.png --- files/opencs/base.png | Bin 0 -> 460 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 files/opencs/base.png diff --git a/files/opencs/base.png b/files/opencs/base.png new file mode 100644 index 0000000000000000000000000000000000000000..4398e2d687b72da2a27ad5b5172d4a746f462be3 GIT binary patch literal 460 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmSQK*5Dp-y;YjHK@;M7UB8!2P z6$mqaNSWjX6qGD+jVKAuPb(=;EJ|f4FE7{2%*!rLPAo{(%P&fw{mw>;fq~J})5S3) zqV?@`d%wd5GOhNPSMZ+UEZ?Azou;B9VOzkecVLpY!G!9RR}4bN#b)Ivcr}vL*M=NQ zX!l!qW7Qnh{7p}ue795o_noDHNv9$BHs8Yh2i!MYuKke;aFF3xz&fw-I)`!5)MYRC zPBH4JzHGAQ`fG`bZiD%@(}IFTTm>37=~OpFuBf+LaglM+!oFSWE=I{8b@B3?_dJgw zDtpzcUo0jYzJ8g2TV&9xO_E>RZadK yi< Date: Fri, 21 Jun 2013 20:19:35 +0200 Subject: [PATCH 169/213] Fading for Exterior->Interior cell transitions --- apps/openmw/mwworld/scene.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index aec00a8c6..22facdcaf 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" /// FIXME #include "../mwbase/soundmanager.hpp" @@ -353,7 +355,7 @@ namespace MWWorld void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) { - + MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.5); const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); @@ -422,6 +424,7 @@ namespace MWWorld MWBase::Environment::get().getWorld()->adjustSky(); mCellChanged = true; + MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.5); MWBase::Environment::get().getWindowManager ()->loadingDone (); } From a73b97d125b4448586c72eb4716c6061890c2d62 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 21 Jun 2013 23:23:43 -0500 Subject: [PATCH 170/213] Fixed broken references and other bugs Removed references to CSVSettings::SamplePage class Removed multiple QDebug references Fixed custom LineEdits (window size user pref) would not accept data --- apps/launcher/settings/gamesettings.cpp | 2 -- apps/launcher/settings/settingsbase.hpp | 2 -- apps/opencs/model/doc/document.cpp | 3 --- apps/opencs/model/settings/settingsitem.cpp | 19 ++++++++++++++++--- apps/opencs/model/settings/usersettings.cpp | 4 ---- apps/opencs/view/doc/view.cpp | 1 - apps/opencs/view/doc/viewmanager.cpp | 1 - apps/opencs/view/settings/proxyblock.cpp | 3 +++ .../view/settings/usersettingsdialog.cpp | 4 ---- apps/opencs/view/settings/windowpage.cpp | 2 ++ .../fileorderlist/model/datafilesmodel.cpp | 3 ++- 11 files changed, 23 insertions(+), 21 deletions(-) diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 1b0a2e9bf..205879bc3 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -6,8 +6,6 @@ #include #include -#include - #include #include diff --git a/apps/launcher/settings/settingsbase.hpp b/apps/launcher/settings/settingsbase.hpp index 6bf2eff66..ed8ada56c 100644 --- a/apps/launcher/settings/settingsbase.hpp +++ b/apps/launcher/settings/settingsbase.hpp @@ -7,8 +7,6 @@ #include #include -#include - template class SettingsBase { diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 7a66487fb..a4e357416 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -1,9 +1,6 @@ - #include "document.hpp" - #include -#include void CSMDoc::Document::load (const std::vector::const_iterator& begin, const std::vector::const_iterator& end, bool lastAsModified) { diff --git a/apps/opencs/model/settings/settingsitem.cpp b/apps/opencs/model/settings/settingsitem.cpp index 2e6172cb8..5d897448a 100644 --- a/apps/opencs/model/settings/settingsitem.cpp +++ b/apps/opencs/model/settings/settingsitem.cpp @@ -1,5 +1,7 @@ #include "settingsitem.hpp" +#include + bool CSMSettings::SettingsItem::updateItem (const QStringList *values) { QStringList::ConstIterator it = values->begin(); @@ -66,10 +68,21 @@ bool CSMSettings::SettingsItem::updateItem(int valueListIndex) bool CSMSettings::SettingsItem::validate (const QString &value) { - //validation required only if a value list or min/max value pair has been provided - bool isValid = (mValueList->find(value) != mValueList->end()); + //if there is no value list or value pair, there is no validation to do + bool isValid = !(!mValueList->isEmpty() || mValuePair); - if (!isValid && mValuePair) + if (!isValid && !mValueList->isEmpty()) + { + for (QStringList::Iterator it = mValueList->begin(); it != mValueList->end(); ++it) + // foreach (QString listItem, *mValueList) + { + isValid = (value == *it); + + if (isValid) + break; + } + } + else if (!isValid && mValuePair) { int numVal = value.toInt(); diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 5bd2343cd..2175c7364 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -9,16 +9,12 @@ #include #include - #include #include - #include "settingcontainer.hpp" - #include -#include /** * Workaround for problems with whitespaces in paths in older versions of Boost library */ diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index ad88467df..e82629ff2 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include "../../model/doc/document.hpp" #include "../world/subviews.hpp" diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 7e00697c3..bf9da68a0 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -21,7 +21,6 @@ #include #include -#include void CSVDoc::ViewManager::updateIndices() { std::map > documents; diff --git a/apps/opencs/view/settings/proxyblock.cpp b/apps/opencs/view/settings/proxyblock.cpp index e13934fc0..81cc54fca 100644 --- a/apps/opencs/view/settings/proxyblock.cpp +++ b/apps/opencs/view/settings/proxyblock.cpp @@ -53,6 +53,8 @@ bool CSVSettings::ProxyBlock::updateProxiedSettings() bool success = false; int i = 0; + + //find the value index of the selected value in the proxy setting for (; i < mValueList->size(); ++i) { success = (value == mValueList->at(i)); @@ -64,6 +66,7 @@ bool CSVSettings::ProxyBlock::updateProxiedSettings() if (!success) return false; + // update the containing the proxied item's name foreach (QStringList *list, mProxyList) { if ( list->at(0) == block->objectName()) diff --git a/apps/opencs/view/settings/usersettingsdialog.cpp b/apps/opencs/view/settings/usersettingsdialog.cpp index 0f38bf560..64b9aacff 100644 --- a/apps/opencs/view/settings/usersettingsdialog.cpp +++ b/apps/opencs/view/settings/usersettingsdialog.cpp @@ -12,10 +12,6 @@ #include -#include "samplepage.hpp" - -#include - #include "editorpage.hpp" #include "windowpage.hpp" diff --git a/apps/opencs/view/settings/windowpage.cpp b/apps/opencs/view/settings/windowpage.cpp index fa7ee9b3e..5bf5f2161 100644 --- a/apps/opencs/view/settings/windowpage.cpp +++ b/apps/opencs/view/settings/windowpage.cpp @@ -64,12 +64,14 @@ CSVSettings::GroupBlockDef *CSVSettings::WindowPage::buildCustomWindowSize() SettingsItemDef *widthItem = new SettingsItemDef ("Width", "640"); widthItem->widget = WidgetDef (Widget_LineEdit); widthItem->widget.widgetWidth = 45; + widthItem->widget.inputMask = "9999"; //custom height SettingsItemDef *heightItem = new SettingsItemDef ("Height", "480"); heightItem->widget = WidgetDef (Widget_LineEdit); heightItem->widget.widgetWidth = 45; heightItem->widget.caption = "x"; + heightItem->widget.inputMask = "9999"; block->settingItems << widthItem << heightItem; block->widgetOrientation = Orient_Horizontal; diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index 9f2e470b2..02a6766b0 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include @@ -12,6 +11,8 @@ #include "datafilesmodel.hpp" +#include + DataFilesModel::DataFilesModel(QObject *parent) : QAbstractTableModel(parent) { From 62e164b2aa918906a830c58a7c74f5ade645c4a2 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 22 Jun 2013 07:43:28 -0500 Subject: [PATCH 171/213] Fixed load file error if no file is found --- apps/opencs/model/settings/usersettings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 2175c7364..c17f28d4e 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -177,9 +177,9 @@ void CSMSettings::UserSettings::loadFromFile(const QString &filePath) } mSectionSettings.insert(section, settings); - } - stream->device()->close(); + stream->device()->close(); + } return; } From 0e29286856653bce1e73a1e409cfd422146d7808 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sat, 22 Jun 2013 19:15:13 +0200 Subject: [PATCH 172/213] fix custom resolution maximum --- apps/launcher/graphicspage.cpp | 17 ++++++++++++++++- apps/launcher/graphicspage.hpp | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 700ba3db9..d9e10e764 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -35,7 +35,7 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g setupUi(this); // Set the maximum res we can set in windowed mode - QRect res = QApplication::desktop()->screenGeometry(); + QRect res = getMaximumResolution(); customWidthSpinBox->setMaximum(res.width()); customHeightSpinBox->setMaximum(res.height()); @@ -289,6 +289,21 @@ QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer) return result; } +QRect GraphicsPage::getMaximumResolution() +{ + QRect max, res; + int i, screens = QApplication::desktop()->screenCount(); + for (i = 0; i < screens; i++) + { + res = QApplication::desktop()->screenGeometry(i); + if (res.width() > max.width()) + max.setWidth(res.width()); + if (res.height() > max.height()) + max.setHeight(res.height()); + } + return max; +} + void GraphicsPage::rendererChanged(const QString &renderer) { mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString()); diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index 21039af43..37f56d2bb 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -56,6 +56,7 @@ private: QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer); QStringList getAvailableResolutions(Ogre::RenderSystem *renderer); + QRect getMaximumResolution(); void loadSettings(); From d61c12ccfce9a464f38b645ae91ec79cb0071b85 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 22 Jun 2013 20:32:11 +0200 Subject: [PATCH 173/213] minor cleanup --- apps/launcher/graphicspage.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index d9e10e764..157702af4 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -291,11 +291,11 @@ QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer) QRect GraphicsPage::getMaximumResolution() { - QRect max, res; - int i, screens = QApplication::desktop()->screenCount(); - for (i = 0; i < screens; i++) + QRect max; + int screens = QApplication::desktop()->screenCount(); + for (int i = 0; i < screens; ++i) { - res = QApplication::desktop()->screenGeometry(i); + QRect res = QApplication::desktop()->screenGeometry(i); if (res.width() > max.width()) max.setWidth(res.width()); if (res.height() > max.height()) From 16a27e28f7b8e572090055daea79da118c96c95b Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Sat, 22 Jun 2013 21:01:27 -0400 Subject: [PATCH 174/213] inluded gmsts with default values to creation of new base files --- apps/opencs/model/doc/document.cpp | 1941 +++++++++++++++++++++++++++- apps/opencs/model/doc/document.hpp | 2 + 2 files changed, 1939 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 7a66487fb..369331244 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -4,6 +4,9 @@ #include #include + +#include + void CSMDoc::Document::load (const std::vector::const_iterator& begin, const std::vector::const_iterator& end, bool lastAsModified) { @@ -21,6 +24,1927 @@ void CSMDoc::Document::load (const std::vector::const_i getData().loadFile (*end2, false); } +void CSMDoc::Document::addBaseGmsts() +{ + static const char *gmstFloats[] = + { + "fAIFleeFleeMult", + "fAIFleeHealthMult", + "fAIMagicSpellMult", + "fAIMeleeArmorMult", + "fAIMeleeSummWeaponMult", + "fAIMeleeWeaponMult", + "fAIRangeMagicSpellMult", + "fAIRangeMeleeWeaponMult", + "fAlarmRadius", + "fAthleticsRunBonus", + "fAudioDefaultMaxDistance", + "fAudioDefaultMinDistance", + "fAudioMaxDistanceMult", + "fAudioMinDistanceMult", + "fAudioVoiceDefaultMaxDistance", + "fAudioVoiceDefaultMinDistance", + "fAutoPCSpellChance", + "fAutoSpellChance", + "fBargainOfferBase", + "fBargainOfferMulti", + "fBarterGoldResetDelay", + "fBaseRunMultiplier", + "fBlockStillBonus", + "fBribe1000Mod", + "fBribe100Mod", + "fBribe10Mod", + "fCombatAngleXY", + "fCombatAngleZ", + "fCombatArmorMinMult", + "fCombatBlockLeftAngle", + "fCombatBlockRightAngle", + "fCombatCriticalStrikeMult", + "fCombatDelayCreature", + "fCombatDelayNPC", + "fCombatDistance", + "fCombatDistanceWerewolfMod", + "fCombatForceSideAngle", + "fCombatInvisoMult", + "fCombatKODamageMult", + "fCombatTorsoSideAngle", + "fCombatTorsoStartPercent", + "fCombatTorsoStopPercent", + "fConstantEffectMult", + "fCorpseClearDelay", + "fCorpseRespawnDelay", + "fCrimeGoldDiscountMult", + "fCrimeGoldTurnInMult", + "fCrimeStealing", + "fDamageStrengthBase", + "fDamageStrengthMult", + "fDifficultyMult", + "fDiseaseXferChance", + "fDispAttacking", + "fDispBargainFailMod", + "fDispBargainSuccessMod", + "fDispCrimeMod", + "fDispDiseaseMod", + "fDispFactionMod", + "fDispFactionRankBase", + "fDispFactionRankMult", + "fDispositionMod", + "fDispPersonalityBase", + "fDispPersonalityMult", + "fDispPickPocketMod", + "fDispRaceMod", + "fDispStealing", + "fDispWeaponDrawn", + "fEffectCostMult", + "fElementalShieldMult", + "fEnchantmentChanceMult", + "fEnchantmentConstantChanceMult", + "fEnchantmentConstantDurationMult", + "fEnchantmentMult", + "fEnchantmentValueMult", + "fEncumberedMoveEffect", + "fEncumbranceStrMult", + "fEndFatigueMult", + "fFallAcroBase", + "fFallAcroMult", + "fFallDamageDistanceMin", + "fFallDistanceBase", + "fFallDistanceMult", + "fFatigueAttackBase", + "fFatigueAttackMult", + "fFatigueBase", + "fFatigueBlockBase", + "fFatigueBlockMult", + "fFatigueJumpBase", + "fFatigueJumpMult", + "fFatigueMult", + "fFatigueReturnBase", + "fFatigueReturnMult", + "fFatigueRunBase", + "fFatigueRunMult", + "fFatigueSneakBase", + "fFatigueSneakMult", + "fFatigueSpellBase", + "fFatigueSpellCostMult", + "fFatigueSpellMult", + "fFatigueSwimRunBase", + "fFatigueSwimRunMult", + "fFatigueSwimWalkBase", + "fFatigueSwimWalkMult", + "fFightDispMult", + "fFightDistanceMultiplier", + "fFightStealing", + "fFleeDistance", + "fGreetDistanceReset", + "fHandtoHandHealthPer", + "fHandToHandReach", + "fHoldBreathEndMult", + "fHoldBreathTime", + "fIdleChanceMultiplier", + "fIngredientMult", + "fInteriorHeadTrackMult", + "fJumpAcrobaticsBase", + "fJumpAcroMultiplier", + "fJumpEncumbranceBase", + "fJumpEncumbranceMultiplier", + "fJumpMoveBase", + "fJumpMoveMult", + "fJumpRunMultiplier", + "fKnockDownMult", + "fLevelMod", + "fLevelUpHealthEndMult", + "fLightMaxMod", + "fLuckMod", + "fMagesGuildTravel", + "fMagicCreatureCastDelay", + "fMagicDetectRefreshRate", + "fMagicItemConstantMult", + "fMagicItemCostMult", + "fMagicItemOnceMult", + "fMagicItemPriceMult", + "fMagicItemRechargePerSecond", + "fMagicItemStrikeMult", + "fMagicItemUsedMult", + "fMagicStartIconBlink", + "fMagicSunBlockedMult", + "fMajorSkillBonus", + "fMaxFlySpeed", + "fMaxHandToHandMult", + "fMaxHeadTrackDistance", + "fMaxWalkSpeed", + "fMaxWalkSpeedCreature", + "fMedMaxMod", + "fMessageTimePerChar", + "fMinFlySpeed", + "fMinHandToHandMult", + "fMinorSkillBonus", + "fMinWalkSpeed", + "fMinWalkSpeedCreature", + "fMiscSkillBonus", + "fNPCbaseMagickaMult", + "fNPCHealthBarFade", + "fNPCHealthBarTime", + "fPCbaseMagickaMult", + "fPerDieRollMult", + "fPersonalityMod", + "fPerTempMult", + "fPickLockMult", + "fPickPocketMod", + "fPotionMinUsefulDuration", + "fPotionStrengthMult", + "fPotionT1DurMult", + "fPotionT1MagMult", + "fPotionT4BaseStrengthMult", + "fPotionT4EquipStrengthMult", + "fProjectileMaxSpeed", + "fProjectileMinSpeed", + "fProjectileThrownStoreChance", + "fRepairAmountMult", + "fRepairMult", + "fReputationMod", + "fRestMagicMult", + "fSeriousWoundMult", + "fSleepRandMod", + "fSleepRestMod", + "fSneakBootMult", + "fSneakDistanceBase", + "fSneakDistanceMultiplier", + "fSneakNoViewMult", + "fSneakSkillMult", + "fSneakSpeedMultiplier", + "fSneakUseDelay", + "fSneakUseDist", + "fSneakViewMult", + "fSoulGemMult", + "fSpecialSkillBonus", + "fSpellMakingValueMult", + "fSpellPriceMult", + "fSpellValueMult", + "fStromWalkMult", + "fStromWindSpeed", + "fSuffocationDamage", + "fSwimHeightScale", + "fSwimRunAthleticsMult", + "fSwimRunBase", + "fSwimWalkAthleticsMult", + "fSwimWalkBase", + "fSwingBlockBase", + "fSwingBlockMult", + "fTargetSpellMaxSpeed", + "fThrownWeaponMaxSpeed", + "fThrownWeaponMinSpeed", + "fTrapCostMult", + "fTravelMult", + "fTravelTimeMult", + "fUnarmoredBase1", + "fUnarmoredBase2", + "fVanityDelay", + "fVoiceIdleOdds", + "fWaterReflectUpdateAlways", + "fWaterReflectUpdateSeldom", + "fWeaponDamageMult", + "fWeaponFatigueBlockMult", + "fWeaponFatigueMult", + "fWereWolfAcrobatics", + "fWereWolfAgility", + "fWereWolfAlchemy", + "fWereWolfAlteration", + "fWereWolfArmorer", + "fWereWolfAthletics", + "fWereWolfAxe", + "fWereWolfBlock", + "fWereWolfBluntWeapon", + "fWereWolfConjuration", + "fWereWolfDestruction", + "fWereWolfEnchant", + "fWereWolfEndurance", + "fWereWolfFatigue", + "fWereWolfHandtoHand", + "fWereWolfHealth", + "fWereWolfHeavyArmor", + "fWereWolfIllusion", + "fWereWolfIntellegence", + "fWereWolfLightArmor", + "fWereWolfLongBlade", + "fWereWolfLuck", + "fWereWolfMagicka", + "fWereWolfMarksman", + "fWereWolfMediumArmor", + "fWereWolfMerchantile", + "fWereWolfMysticism", + "fWereWolfPersonality", + "fWereWolfRestoration", + "fWereWolfRunMult", + "fWereWolfSecurity", + "fWereWolfShortBlade", + "fWereWolfSilverWeaponDamageMult", + "fWereWolfSneak", + "fWereWolfSpear", + "fWereWolfSpeechcraft", + "fWereWolfSpeed", + "fWereWolfStrength", + "fWereWolfUnarmored", + "fWereWolfWillPower", + "fWortChanceValue", + 0 + }; + + static const float gmstFloatsValues[] = + { + 0.3, // fAIFleeFleeMult + 7.0, // fAIFleeHealthMult + 3.0, // fAIMagicSpellMult + 1.0, // fAIMeleeArmorMult + 1.0, // fAIMeleeSummWeaponMult + 2.0, // fAIMeleeWeaponMult + 5.0, // fAIRangeMagicSpellMult + 5.0, // fAIRangeMeleeWeaponMult + 2000.0, // fAlarmRadius + 1.0, // fAthleticsRunBonus + 40.0, // fAudioDefaultMaxDistance + 5.0, // fAudioDefaultMinDistance + 50.0, // fAudioMaxDistanceMult + 20.0, // fAudioMinDistanceMult + 60.0, // fAudioVoiceDefaultMaxDistance + 10.0, // fAudioVoiceDefaultMinDistance + 50.0, // fAutoPCSpellChance + 80.0, // fAutoSpellChance + 50.0, // fBargainOfferBase + -4.0, // fBargainOfferMulti + 24.0, // fBarterGoldResetDelay + 1.75, // fBaseRunMultiplier + 1.25, // fBlockStillBonus + 150.0, // fBribe1000Mod + 75.0, // fBribe100Mod + 35.0, // fBribe10Mod + 60.0, // fCombatAngleXY + 60.0, // fCombatAngleZ + 0.25, // fCombatArmorMinMult + -90.0, // fCombatBlockLeftAngle + 30.0, // fCombatBlockRightAngle + 4.0, // fCombatCriticalStrikeMult + 0.1, // fCombatDelayCreature + 0.1, // fCombatDelayNPC + 128.0, // fCombatDistance + 0.3, // fCombatDistanceWerewolfMod + 30.0, // fCombatForceSideAngle + 0.2, // fCombatInvisoMult + 1.5, // fCombatKODamageMult + 45.0, // fCombatTorsoSideAngle + 0.3, // fCombatTorsoStartPercent + 0.8, // fCombatTorsoStopPercent + 15.0, // fConstantEffectMult + 72.0, // fCorpseClearDelay + 72.0, // fCorpseRespawnDelay + 0.5, // fCrimeGoldDiscountMult + 0.9, // fCrimeGoldTurnInMult + 1.0, // fCrimeStealing + 0.5, // fDamageStrengthBase + 0.1, // fDamageStrengthMult + 5.0, // fDifficultyMult + 2.5, // fDiseaseXferChance + -10.0, // fDispAttacking + -1.0, // fDispBargainFailMod + 1.0, // fDispBargainSuccessMod + 0.0, // fDispCrimeMod + -10.0, // fDispDiseaseMod + 3.0, // fDispFactionMod + 1.0, // fDispFactionRankBase + 0.5, // fDispFactionRankMult + 1.0, // fDispositionMod + 50.0, // fDispPersonalityBase + 0.5, // fDispPersonalityMult + -25.0, // fDispPickPocketMod + 5.0, // fDispRaceMod + -0.5, // fDispStealing + -5.0, // fDispWeaponDrawn + 0.5, // fEffectCostMult + 0.1, // fElementalShieldMult + 3.0, // fEnchantmentChanceMult + 0.5, // fEnchantmentConstantChanceMult + 100.0, // fEnchantmentConstantDurationMult + 0.1, // fEnchantmentMult + 1000.0, // fEnchantmentValueMult + 0.3, // fEncumberedMoveEffect + 5.0, // fEncumbranceStrMult + 0.04, // fEndFatigueMult + 0.25, // fFallAcroBase + 0.01, // fFallAcroMult + 400.0, // fFallDamageDistanceMin + 0.0, // fFallDistanceBase + 0.07, // fFallDistanceMult + 2.0, // fFatigueAttackBase + 0.0, // fFatigueAttackMult + 1.25, // fFatigueBase + 4.0, // fFatigueBlockBase + 0.0, // fFatigueBlockMult + 5.0, // fFatigueJumpBase + 0.0, // fFatigueJumpMult + 0.5, // fFatigueMult + 2.5, // fFatigueReturnBase + 0.02, // fFatigueReturnMult + 5.0, // fFatigueRunBase + 2.0, // fFatigueRunMult + 1.5, // fFatigueSneakBase + 1.5, // fFatigueSneakMult + 0.0, // fFatigueSpellBase + 0.0, // fFatigueSpellCostMult + 0.0, // fFatigueSpellMult + 7.0, // fFatigueSwimRunBase + 0.0, // fFatigueSwimRunMult + 2.5, // fFatigueSwimWalkBase + 0.0, // fFatigueSwimWalkMult + 0.2, // fFightDispMult + 0.005, // fFightDistanceMultiplier + 50.0, // fFightStealing + 3000.0, // fFleeDistance + 512.0, // fGreetDistanceReset + 0.1, // fHandtoHandHealthPer + 1.0, // fHandToHandReach + 0.5, // fHoldBreathEndMult + 20.0, // fHoldBreathTime + 0.75, // fIdleChanceMultiplier + 1.0, // fIngredientMult + 0.5, // fInteriorHeadTrackMult + 128.0, // fJumpAcrobaticsBase + 4.0, // fJumpAcroMultiplier + 0.5, // fJumpEncumbranceBase + 1.0, // fJumpEncumbranceMultiplier + 0.5, // fJumpMoveBase + 0.5, // fJumpMoveMult + 1.0, // fJumpRunMultiplier + 0.5, // fKnockDownMult + 5.0, // fLevelMod + 0.1, // fLevelUpHealthEndMult + 0.6, // fLightMaxMod + 10.0, // fLuckMod + 10.0, // fMagesGuildTravel + 1.5, // fMagicCreatureCastDelay + 0.0167, // fMagicDetectRefreshRate + 1.0, // fMagicItemConstantMult + 1.0, // fMagicItemCostMult + 1.0, // fMagicItemOnceMult + 1.0, // fMagicItemPriceMult + 0.05, // fMagicItemRechargePerSecond + 1.0, // fMagicItemStrikeMult + 1.0, // fMagicItemUsedMult + 3.0, // fMagicStartIconBlink + 0.5, // fMagicSunBlockedMult + 0.75, // fMajorSkillBonus + 300.0, // fMaxFlySpeed + 0.5, // fMaxHandToHandMult + 400.0, // fMaxHeadTrackDistance + 200.0, // fMaxWalkSpeed + 300.0, // fMaxWalkSpeedCreature + 0.9, // fMedMaxMod + 0.1, // fMessageTimePerChar + 5.0, // fMinFlySpeed + 0.1, // fMinHandToHandMult + 1.0, // fMinorSkillBonus + 100.0, // fMinWalkSpeed + 5.0, // fMinWalkSpeedCreature + 1.25, // fMiscSkillBonus + 2.0, // fNPCbaseMagickaMult + 0.5, // fNPCHealthBarFade + 3.0, // fNPCHealthBarTime + 1.0, // fPCbaseMagickaMult + 0.3, // fPerDieRollMult + 5.0, // fPersonalityMod + 1.0, // fPerTempMult + -1.0, // fPickLockMult + 0.3, // fPickPocketMod + 20.0, // fPotionMinUsefulDuration + 0.5, // fPotionStrengthMult + 0.5, // fPotionT1DurMult + 1.5, // fPotionT1MagMult + 20.0, // fPotionT4BaseStrengthMult + 12.0, // fPotionT4EquipStrengthMult + 3000.0, // fProjectileMaxSpeed + 400.0, // fProjectileMinSpeed + 25.0, // fProjectileThrownStoreChance + 3.0, // fRepairAmountMult + 1.0, // fRepairMult + 1.0, // fReputationMod + 0.15, // fRestMagicMult + 0.0, // fSeriousWoundMult + 0.25, // fSleepRandMod + 0.3, // fSleepRestMod + -1.0, // fSneakBootMult + 0.5, // fSneakDistanceBase + 0.002, // fSneakDistanceMultiplier + 0.5, // fSneakNoViewMult + 1.0, // fSneakSkillMult + 0.75, // fSneakSpeedMultiplier + 1.0, // fSneakUseDelay + 500.0, // fSneakUseDist + 1.5, // fSneakViewMult + 3.0, // fSoulGemMult + 0.8, // fSpecialSkillBonus + 7.0, // fSpellMakingValueMult + 2.0, // fSpellPriceMult + 10.0, // fSpellValueMult + 0.25, // fStromWalkMult + 0.7, // fStromWindSpeed + 3.0, // fSuffocationDamage + 0.9, // fSwimHeightScale + 0.1, // fSwimRunAthleticsMult + 0.5, // fSwimRunBase + 0.02, // fSwimWalkAthleticsMult + 0.5, // fSwimWalkBase + 1.0, // fSwingBlockBase + 1.0, // fSwingBlockMult + 1000.0, // fTargetSpellMaxSpeed + 1000.0, // fThrownWeaponMaxSpeed + 300.0, // fThrownWeaponMinSpeed + 0.0, // fTrapCostMult + 4000.0, // fTravelMult + 16000.0,// fTravelTimeMult + 0.1, // fUnarmoredBase1 + 0.065, // fUnarmoredBase2 + 30.0, // fVanityDelay + 10.0, // fVoiceIdleOdds + 0.0, // fWaterReflectUpdateAlways + 10.0, // fWaterReflectUpdateSeldom + 0.1, // fWeaponDamageMult + 1.0, // fWeaponFatigueBlockMult + 0.25, // fWeaponFatigueMult + 150.0, // fWereWolfAcrobatics + 150.0, // fWereWolfAgility + 1.0, // fWereWolfAlchemy + 1.0, // fWereWolfAlteration + 1.0, // fWereWolfArmorer + 150.0, // fWereWolfAthletics + 1.0, // fWereWolfAxe + 1.0, // fWereWolfBlock + 1.0, // fWereWolfBluntWeapon + 1.0, // fWereWolfConjuration + 1.0, // fWereWolfDestruction + 1.0, // fWereWolfEnchant + 150.0, // fWereWolfEndurance + 400.0, // fWereWolfFatigue + 100.0, // fWereWolfHandtoHand + 2.0, // fWereWolfHealth + 1.0, // fWereWolfHeavyArmor + 1.0, // fWereWolfIllusion + 1.0, // fWereWolfIntellegence + 1.0, // fWereWolfLightArmor + 1.0, // fWereWolfLongBlade + 1.0, // fWereWolfLuck + 100.0, // fWereWolfMagicka + 1.0, // fWereWolfMarksman + 1.0, // fWereWolfMediumArmor + 1.0, // fWereWolfMerchantile + 1.0, // fWereWolfMysticism + 1.0, // fWereWolfPersonality + 1.0, // fWereWolfRestoration + 1.5, // fWereWolfRunMult + 1.0, // fWereWolfSecurity + 1.0, // fWereWolfShortBlade + 1.5, // fWereWolfSilverWeaponDamageMult + 1.0, // fWereWolfSneak + 1.0, // fWereWolfSpear + 1.0, // fWereWolfSpeechcraft + 150.0, // fWereWolfSpeed + 150.0, // fWereWolfStrength + 100.0, // fWereWolfUnarmored + 1.0, // fWereWolfWillPower + 15.0, // fWortChanceValue + }; + + static const char *gmstIntegers[] = + { + "i1stPersonSneakDelta", + "iAlarmAttack", + "iAlarmKilling", + "iAlarmPickPocket", + "iAlarmStealing", + "iAlarmTresspass", + "iAlchemyMod", + "iAutoPCSpellMax", + "iAutoRepFacMod", + "iAutoRepLevMod", + "iAutoSpellAlterationMax", + "iAutoSpellAttSkillMin", + "iAutoSpellConjurationMax", + "iAutoSpellDestructionMax", + "iAutoSpellIllusionMax", + "iAutoSpellMysticismMax", + "iAutoSpellRestorationMax", + "iAutoSpellTimesCanCast", + "iBarterFailDisposition", + "iBarterSuccessDisposition", + "iBaseArmorSkill", + "iBlockMaxChance", + "iBlockMinChance", + "iBootsWeight", + "iCrimeAttack", + "iCrimeKilling", + "iCrimePickPocket", + "iCrimeThreshold", + "iCrimeThresholdMultiplier", + "iCrimeTresspass", + "iCuirassWeight", + "iDaysinPrisonMod", + "iDispAttackMod", + "iDispKilling", + "iDispTresspass", + "iFightAlarmMult", + "iFightAttack", + "iFightAttacking", + "iFightDistanceBase", + "iFightKilling", + "iFightPickpocket", + "iFightTrespass", + "iFlee", + "iGauntletWeight", + "iGreavesWeight", + "iGreetDistanceMultiplier", + "iGreetDuration", + "iHelmWeight", + "iKnockDownOddsBase", + "iKnockDownOddsMult", + "iLevelUp01Mult", + "iLevelUp02Mult", + "iLevelUp03Mult", + "iLevelUp04Mult", + "iLevelUp05Mult", + "iLevelUp06Mult", + "iLevelUp07Mult", + "iLevelUp08Mult", + "iLevelUp09Mult", + "iLevelUp10Mult", + "iLevelupMajorMult", + "iLevelupMajorMultAttribute", + "iLevelupMinorMult", + "iLevelupMinorMultAttribute", + "iLevelupMiscMultAttriubte", + "iLevelupSpecialization", + "iLevelupTotal", + "iMagicItemChargeConst", + "iMagicItemChargeOnce", + "iMagicItemChargeStrike", + "iMagicItemChargeUse", + "iMaxActivateDist", + "iMaxInfoDist", + "iMonthsToRespawn", + "iNumberCreatures", + "iPauldronWeight", + "iPerMinChance", + "iPerMinChange", + "iPickMaxChance", + "iPickMinChance", + "iShieldWeight", + "iSoulAmountForConstantEffect", + "iTrainingMod", + "iVoiceAttackOdds", + "iVoiceHitOdds", + "iWereWolfBounty", + "iWereWolfFightMod", + "iWereWolfFleeMod", + "iWereWolfLevelToAttack", + 0 + }; + + static const int gmstIntegersValues[] = + { + 10, // i1stPersonSneakDelta + 50, // iAlarmAttack + 90, // iAlarmKilling + 20, // iAlarmPickPocket + 1, // iAlarmStealing + 5, // iAlarmTresspass + 2, // iAlchemyMod + 100, // iAutoPCSpellMax + 2, // iAutoRepFacMod + 0, // iAutoRepLevMod + 5, // iAutoSpellAlterationMax + 70, // iAutoSpellAttSkillMin + 2, // iAutoSpellConjurationMax + 5, // iAutoSpellDestructionMax + 5, // iAutoSpellIllusionMax + 5, // iAutoSpellMysticismMax + 5, // iAutoSpellRestorationMax + 3, // iAutoSpellTimesCanCast + -1, // iBarterFailDisposition + 1, // iBarterSuccessDisposition + 30, // iBaseArmorSkill + 50, // iBlockMaxChance + 10, // iBlockMinChance + 20, // iBootsWeight + 40, // iCrimeAttack + 1000, // iCrimeKilling + 25, // iCrimePickPocket + 1000, // iCrimeThreshold + 10, // iCrimeThresholdMultiplier + 5, // iCrimeTresspass + 30, // iCuirassWeight + 100, // iDaysinPrisonMod + -50, // iDispAttackMod + -50, // iDispKilling + -20, // iDispTresspass + 1, // iFightAlarmMult + 100, // iFightAttack + 50, // iFightAttacking + 20, // iFightDistanceBase + 50, // iFightKilling + 25, // iFightPickpocket + 25, // iFightTrespass + 0, // iFlee + 5, // iGauntletWeight + 15, // iGreavesWeight + 6, // iGreetDistanceMultiplier + 4, // iGreetDuration + 5, // iHelmWeight + 50, // iKnockDownOddsBase + 50, // iKnockDownOddsMult + 2, // iLevelUp01Mult + 2, // iLevelUp02Mult + 2, // iLevelUp03Mult + 2, // iLevelUp04Mult + 3, // iLevelUp05Mult + 3, // iLevelUp06Mult + 3, // iLevelUp07Mult + 4, // iLevelUp08Mult + 4, // iLevelUp09Mult + 5, // iLevelUp10Mult + 1, // iLevelupMajorMult + 1, // iLevelupMajorMultAttribute + 1, // iLevelupMinorMult + 1, // iLevelupMinorMultAttribute + 1, // iLevelupMiscMultAttriubte + 1, // iLevelupSpecialization + 10, // iLevelupTotal + 10, // iMagicItemChargeConst + 1, // iMagicItemChargeOnce + 10, // iMagicItemChargeStrike + 5, // iMagicItemChargeUse + 192, // iMaxActivateDist + 192, // iMaxInfoDist + 4, // iMonthsToRespawn + 1, // iNumberCreatures + 10, // iPauldronWeight + 5, // iPerMinChance + 10, // iPerMinChange + 75, // iPickMaxChance + 5, // iPickMinChance + 15, // iShieldWeight + 400, // iSoulAmountForConstantEffect + 10, // iTrainingMod + 10, // iVoiceAttackOdds + 30, // iVoiceHitOdds + 10000, // iWereWolfBounty + 100, // iWereWolfFightMod + 100, // iWereWolfFleeMod + 20, // iWereWolfLevelToAttack + }; + + static const char *gmstStrings[] = + { + "s3dAudio", + "s3dHardware", + "s3dSoftware", + "sAbsorb", + "sAcrobat", + "sActivate", + "sActivateXbox", + "sActorInCombat", + "sAdmire", + "sAdmireFail", + "sAdmireSuccess", + "sAgent", + "sAgiDesc", + "sAIDistance", + "sAlembic", + "sAllTab", + "sAlways", + "sAlways_Run", + "sand", + "sApparatus", + "sApparelTab", + "sArcher", + "sArea", + "sAreaDes", + "sArmor", + "sArmorRating", + "sAsk", + "sAssassin", + "sAt", + "sAttack", + "sAttributeAgility", + "sAttributeEndurance", + "sAttributeIntelligence", + "sAttributeListTitle", + "sAttributeLuck", + "sAttributePersonality", + "sAttributesMenu1", + "sAttributeSpeed", + "sAttributeStrength", + "sAttributeWillpower", + "sAudio", + "sAuto_Run", + "sBack", + "sBackspace", + "sBackXbox", + "sBarbarian", + "sBard", + "sBarter", + "sBarterDialog1", + "sBarterDialog10", + "sBarterDialog11", + "sBarterDialog12", + "sBarterDialog2", + "sBarterDialog3", + "sBarterDialog4", + "sBarterDialog5", + "sBarterDialog6", + "sBarterDialog7", + "sBarterDialog8", + "sBarterDialog9", + "sBattlemage", + "sBestAttack", + "sBirthSign", + "sBirthsignmenu1", + "sBirthsignmenu2", + "sBlocks", + "sBonusSkillTitle", + "sBookPageOne", + "sBookPageTwo", + "sBookSkillMessage", + "sBounty", + "sBreath", + "sBribe", + "sBribe", + "sBribe", + "sBribeFail", + "sBribeSuccess", + "sBuy", + "sBye", + "sCalcinator", + "sCancel", + "sCantEquipWeapWarning", + "sCastCost", + "sCaughtStealingMessage", + "sCenter", + "sChangedMastersMsg", + "sCharges", + "sChooseClassMenu1", + "sChooseClassMenu2", + "sChooseClassMenu3", + "sChooseClassMenu4", + "sChop", + "sClass", + "sClassChoiceMenu1", + "sClassChoiceMenu2", + "sClassChoiceMenu3", + "sClose", + "sCompanionShare", + "sCompanionWarningButtonOne", + "sCompanionWarningButtonTwo", + "sCompanionWarningMessage", + "sCondition", + "sConsoleTitle", + "sContainer", + "sContentsMessage1", + "sContentsMessage2", + "sContentsMessage3", + "sControlerVibration", + "sControls", + "sControlsMenu1", + "sControlsMenu2", + "sControlsMenu3", + "sControlsMenu4", + "sControlsMenu5", + "sControlsMenu6", + "sCostChance", + "sCostCharge", + "sCreate", + "sCreateClassMenu1", + "sCreateClassMenu2", + "sCreateClassMenu3", + "sCreateClassMenuHelp1", + "sCreateClassMenuHelp2", + "sCreateClassMenuWarning", + "sCreatedEffects", + "sCrimeHelp", + "sCrimeMessage", + "sCrouch_Sneak", + "sCrouchXbox", + "sCrusader", + "sCursorOff", + "sCustom", + "sCustomClassName", + "sDamage", + "sDark_Gamma", + "sDay", + "sDefaultCellname", + "sDelete", + "sDeleteGame", + "sDeleteNote", + "sDeleteSpell", + "sDeleteSpellError", + "sDetail_Level", + "sDialogMenu1", + "sDialogText1Xbox", + "sDialogText2Xbox", + "sDialogText3Xbox", + "sDifficulty", + "sDisposeCorpseFail", + "sDisposeofCorpse", + "sDone", + "sDoYouWantTo", + "sDrain", + "sDrop", + "sDuration", + "sDurationDes", + "sEasy", + "sEditNote", + "sEffectAbsorbAttribute", + "sEffectAbsorbFatigue", + "sEffectAbsorbHealth", + "sEffectAbsorbSkill", + "sEffectAbsorbSpellPoints", + "sEffectAlmsiviIntervention", + "sEffectBlind", + "sEffectBoundBattleAxe", + "sEffectBoundBoots", + "sEffectBoundCuirass", + "sEffectBoundDagger", + "sEffectBoundGloves", + "sEffectBoundHelm", + "sEffectBoundLongbow", + "sEffectBoundLongsword", + "sEffectBoundMace", + "sEffectBoundShield", + "sEffectBoundSpear", + "sEffectBurden", + "sEffectCalmCreature", + "sEffectCalmHumanoid", + "sEffectChameleon", + "sEffectCharm", + "sEffectCommandCreatures", + "sEffectCommandHumanoids", + "sEffectCorpus", + "sEffectCureBlightDisease", + "sEffectCureCommonDisease", + "sEffectCureCorprusDisease", + "sEffectCureParalyzation", + "sEffectCurePoison", + "sEffectDamageAttribute", + "sEffectDamageFatigue", + "sEffectDamageHealth", + "sEffectDamageMagicka", + "sEffectDamageSkill", + "sEffectDemoralizeCreature", + "sEffectDemoralizeHumanoid", + "sEffectDetectAnimal", + "sEffectDetectEnchantment", + "sEffectDetectKey", + "sEffectDisintegrateArmor", + "sEffectDisintegrateWeapon", + "sEffectDispel", + "sEffectDivineIntervention", + "sEffectDrainAttribute", + "sEffectDrainFatigue", + "sEffectDrainHealth", + "sEffectDrainSkill", + "sEffectDrainSpellpoints", + "sEffectExtraSpell", + "sEffectFeather", + "sEffectFireDamage", + "sEffectFireShield", + "sEffectFortifyAttackBonus", + "sEffectFortifyAttribute", + "sEffectFortifyFatigue", + "sEffectFortifyHealth", + "sEffectFortifyMagickaMultiplier", + "sEffectFortifySkill", + "sEffectFortifySpellpoints", + "sEffectFrenzyCreature", + "sEffectFrenzyHumanoid", + "sEffectFrostDamage", + "sEffectFrostShield", + "sEffectInvisibility", + "sEffectJump", + "sEffectLevitate", + "sEffectLight", + "sEffectLightningShield", + "sEffectLock", + "sEffectMark", + "sEffectNightEye", + "sEffectOpen", + "sEffectParalyze", + "sEffectPoison", + "sEffectRallyCreature", + "sEffectRallyHumanoid", + "sEffectRecall", + "sEffectReflect", + "sEffectRemoveCurse", + "sEffectResistBlightDisease", + "sEffectResistCommonDisease", + "sEffectResistCorprusDisease", + "sEffectResistFire", + "sEffectResistFrost", + "sEffectResistMagicka", + "sEffectResistNormalWeapons", + "sEffectResistParalysis", + "sEffectResistPoison", + "sEffectResistShock", + "sEffectRestoreAttribute", + "sEffectRestoreFatigue", + "sEffectRestoreHealth", + "sEffectRestoreSkill", + "sEffectRestoreSpellPoints", + "sEffects", + "sEffectSanctuary", + "sEffectShield", + "sEffectShockDamage", + "sEffectSilence", + "sEffectSlowFall", + "sEffectSoultrap", + "sEffectSound", + "sEffectSpellAbsorption", + "sEffectStuntedMagicka", + "sEffectSummonAncestralGhost", + "sEffectSummonBonelord", + "sEffectSummonCenturionSphere", + "sEffectSummonClannfear", + "sEffectSummonCreature01", + "sEffectSummonCreature02", + "sEffectSummonCreature03", + "sEffectSummonCreature04", + "sEffectSummonCreature05", + "sEffectSummonDaedroth", + "sEffectSummonDremora", + "sEffectSummonFabricant", + "sEffectSummonFlameAtronach", + "sEffectSummonFrostAtronach", + "sEffectSummonGoldensaint", + "sEffectSummonGreaterBonewalker", + "sEffectSummonHunger", + "sEffectSummonLeastBonewalker", + "sEffectSummonScamp", + "sEffectSummonSkeletalMinion", + "sEffectSummonStormAtronach", + "sEffectSummonWingedTwilight", + "sEffectSunDamage", + "sEffectSwiftSwim", + "sEffectTelekinesis", + "sEffectTurnUndead", + "sEffectVampirism", + "sEffectWaterBreathing", + "sEffectWaterWalking", + "sEffectWeaknessToBlightDisease", + "sEffectWeaknessToCommonDisease", + "sEffectWeaknessToCorprusDisease", + "sEffectWeaknessToFire", + "sEffectWeaknessToFrost", + "sEffectWeaknessToMagicka", + "sEffectWeaknessToNormalWeapons", + "sEffectWeaknessToPoison", + "sEffectWeaknessToShock", + "sEnableJoystick", + "sEnchanting", + "sEnchantItems", + "sEnchantmentHelp1", + "sEnchantmentHelp10", + "sEnchantmentHelp2", + "sEnchantmentHelp3", + "sEnchantmentHelp4", + "sEnchantmentHelp5", + "sEnchantmentHelp6", + "sEnchantmentHelp7", + "sEnchantmentHelp8", + "sEnchantmentHelp9", + "sEnchantmentMenu1", + "sEnchantmentMenu10", + "sEnchantmentMenu11", + "sEnchantmentMenu12", + "sEnchantmentMenu2", + "sEnchantmentMenu3", + "sEnchantmentMenu4", + "sEnchantmentMenu5", + "sEnchantmentMenu6", + "sEnchantmentMenu7", + "sEnchantmentMenu8", + "sEnchantmentMenu9", + "sEncumbrance", + "sEndDesc", + "sEquip", + "sExitGame", + "sExpelled", + "sExpelledMessage", + "sFace", + "sFaction", + "sFar", + "sFast", + "sFatDesc", + "sFatigue", + "sFavoriteSkills", + "sfeet", + "sFileSize", + "sfootarea", + "sFootsteps", + "sfor", + "sFortify", + "sForward", + "sForwardXbox", + "sFull", + "sGame", + "sGameWithoutLauncherXbox", + "sGamma_Correction", + "sGeneralMastPlugMismatchMsg", + "sGold", + "sGoodbye", + "sGoverningAttribute", + "sgp", + "sHair", + "sHard", + "sHeal", + "sHealer", + "sHealth", + "sHealthDesc", + "sHealthPerHourOfRest", + "sHealthPerLevel", + "sHeavy", + "sHigh", + "sin", + "sInfo", + "sInfoRefusal", + "sIngredients", + "sInPrisonTitle", + "sInputMenu1", + "sIntDesc", + "sIntimidate", + "sIntimidateFail", + "sIntimidateSuccess", + "sInvalidSaveGameMsg", + "sInvalidSaveGameMsgXBOX", + "sInventory", + "sInventoryMenu1", + "sInventoryMessage1", + "sInventoryMessage2", + "sInventoryMessage3", + "sInventoryMessage4", + "sInventoryMessage5", + "sInventorySelectNoIngredients", + "sInventorySelectNoItems", + "sInventorySelectNoSoul", + "sItem", + "sItemCastConstant", + "sItemCastOnce", + "sItemCastWhenStrikes", + "sItemCastWhenUsed", + "sItemName", + "sJournal", + "sJournalCmd", + "sJournalEntry", + "sJournalXbox", + "sJoystickHatShort", + "sJoystickNotFound", + "sJoystickShort", + "sJump", + "sJumpXbox", + "sKeyName_00", + "sKeyName_01", + "sKeyName_02", + "sKeyName_03", + "sKeyName_04", + "sKeyName_05", + "sKeyName_06", + "sKeyName_07", + "sKeyName_08", + "sKeyName_09", + "sKeyName_0A", + "sKeyName_0B", + "sKeyName_0C", + "sKeyName_0D", + "sKeyName_0E", + "sKeyName_0F", + "sKeyName_10", + "sKeyName_11", + "sKeyName_12", + "sKeyName_13", + "sKeyName_14", + "sKeyName_15", + "sKeyName_16", + "sKeyName_17", + "sKeyName_18", + "sKeyName_19", + "sKeyName_1A", + "sKeyName_1B", + "sKeyName_1C", + "sKeyName_1D", + "sKeyName_1E", + "sKeyName_1F", + "sKeyName_20", + "sKeyName_21", + "sKeyName_22", + "sKeyName_23", + "sKeyName_24", + "sKeyName_25", + "sKeyName_26", + "sKeyName_27", + "sKeyName_28", + "sKeyName_29", + "sKeyName_2A", + "sKeyName_2B", + "sKeyName_2C", + "sKeyName_2D", + "sKeyName_2E", + "sKeyName_2F", + "sKeyName_30", + "sKeyName_31", + "sKeyName_32", + "sKeyName_33", + "sKeyName_34", + "sKeyName_35", + "sKeyName_36", + "sKeyName_37", + "sKeyName_38", + "sKeyName_39", + "sKeyName_3A", + "sKeyName_3B", + "sKeyName_3C", + "sKeyName_3D", + "sKeyName_3E", + "sKeyName_3F", + "sKeyName_40", + "sKeyName_41", + "sKeyName_42", + "sKeyName_43", + "sKeyName_44", + "sKeyName_45", + "sKeyName_46", + "sKeyName_47", + "sKeyName_48", + "sKeyName_49", + "sKeyName_4A", + "sKeyName_4B", + "sKeyName_4C", + "sKeyName_4D", + "sKeyName_4E", + "sKeyName_4F", + "sKeyName_50", + "sKeyName_51", + "sKeyName_52", + "sKeyName_53", + "sKeyName_54", + "sKeyName_55", + "sKeyName_56", + "sKeyName_57", + "sKeyName_58", + "sKeyName_59", + "sKeyName_5A", + "sKeyName_5B", + "sKeyName_5C", + "sKeyName_5D", + "sKeyName_5E", + "sKeyName_5F", + "sKeyName_60", + "sKeyName_61", + "sKeyName_62", + "sKeyName_63", + "sKeyName_64", + "sKeyName_65", + "sKeyName_66", + "sKeyName_67", + "sKeyName_68", + "sKeyName_69", + "sKeyName_6A", + "sKeyName_6B", + "sKeyName_6C", + "sKeyName_6D", + "sKeyName_6E", + "sKeyName_6F", + "sKeyName_70", + "sKeyName_71", + "sKeyName_72", + "sKeyName_73", + "sKeyName_74", + "sKeyName_75", + "sKeyName_76", + "sKeyName_77", + "sKeyName_78", + "sKeyName_79", + "sKeyName_7A", + "sKeyName_7B", + "sKeyName_7C", + "sKeyName_7D", + "sKeyName_7E", + "sKeyName_7F", + "sKeyName_80", + "sKeyName_81", + "sKeyName_82", + "sKeyName_83", + "sKeyName_84", + "sKeyName_85", + "sKeyName_86", + "sKeyName_87", + "sKeyName_88", + "sKeyName_89", + "sKeyName_8A", + "sKeyName_8B", + "sKeyName_8C", + "sKeyName_8D", + "sKeyName_8E", + "sKeyName_8F", + "sKeyName_90", + "sKeyName_91", + "sKeyName_92", + "sKeyName_93", + "sKeyName_94", + "sKeyName_95", + "sKeyName_96", + "sKeyName_97", + "sKeyName_98", + "sKeyName_99", + "sKeyName_9A", + "sKeyName_9B", + "sKeyName_9C", + "sKeyName_9D", + "sKeyName_9E", + "sKeyName_9F", + "sKeyName_A0", + "sKeyName_A1", + "sKeyName_A2", + "sKeyName_A3", + "sKeyName_A4", + "sKeyName_A5", + "sKeyName_A6", + "sKeyName_A7", + "sKeyName_A8", + "sKeyName_A9", + "sKeyName_AA", + "sKeyName_AB", + "sKeyName_AC", + "sKeyName_AD", + "sKeyName_AE", + "sKeyName_AF", + "sKeyName_B0", + "sKeyName_B1", + "sKeyName_B2", + "sKeyName_B3", + "sKeyName_B4", + "sKeyName_B5", + "sKeyName_B6", + "sKeyName_B7", + "sKeyName_B8", + "sKeyName_B9", + "sKeyName_BA", + "sKeyName_BB", + "sKeyName_BC", + "sKeyName_BD", + "sKeyName_BE", + "sKeyName_BF", + "sKeyName_C0", + "sKeyName_C1", + "sKeyName_C2", + "sKeyName_C3", + "sKeyName_C4", + "sKeyName_C5", + "sKeyName_C6", + "sKeyName_C7", + "sKeyName_C8", + "sKeyName_C9", + "sKeyName_CA", + "sKeyName_CB", + "sKeyName_CC", + "sKeyName_CD", + "sKeyName_CE", + "sKeyName_CF", + "sKeyName_D0", + "sKeyName_D1", + "sKeyName_D2", + "sKeyName_D3", + "sKeyName_D4", + "sKeyName_D5", + "sKeyName_D6", + "sKeyName_D7", + "sKeyName_D8", + "sKeyName_D9", + "sKeyName_DA", + "sKeyName_DB", + "sKeyName_DC", + "sKeyName_DD", + "sKeyName_DE", + "sKeyName_DF", + "sKeyName_E0", + "sKeyName_E1", + "sKeyName_E2", + "sKeyName_E3", + "sKeyName_E4", + "sKeyName_E5", + "sKeyName_E6", + "sKeyName_E7", + "sKeyName_E8", + "sKeyName_E9", + "sKeyName_EA", + "sKeyName_EB", + "sKeyName_EC", + "sKeyName_ED", + "sKeyName_EE", + "sKeyName_EF", + "sKeyName_F0", + "sKeyName_F1", + "sKeyName_F2", + "sKeyName_F3", + "sKeyName_F4", + "sKeyName_F5", + "sKeyName_F6", + "sKeyName_F7", + "sKeyName_F8", + "sKeyName_F9", + "sKeyName_FA", + "sKeyName_FB", + "sKeyName_FC", + "sKeyName_FD", + "sKeyName_FE", + "sKeyName_FF", + "sKeyUsed", + "sKilledEssential", + "sKnight", + "sLeft", + "sLess", + "sLevel", + "sLevelProgress", + "sLevels", + "sLevelUp", + "sLevelUpMenu1", + "sLevelUpMenu2", + "sLevelUpMenu3", + "sLevelUpMenu4", + "sLevelUpMsg", + "sLevitateDisabled", + "sLight", + "sLight_Gamma", + "sLoadFailedMessage", + "sLoadGame", + "sLoadingErrorsMsg", + "sLoadingMessage1", + "sLoadingMessage14", + "sLoadingMessage15", + "sLoadingMessage2", + "sLoadingMessage3", + "sLoadingMessage4", + "sLoadingMessage5", + "sLoadingMessage9", + "sLoadLastSaveMsg", + "sLocal", + "sLockFail", + "sLockImpossible", + "sLockLevel", + "sLockSuccess", + "sLookDownXbox", + "sLookUpXbox", + "sLow", + "sLucDesc", + "sMagDesc", + "sMage", + "sMagic", + "sMagicAncestralGhostID", + "sMagicBonelordID", + "sMagicBoundBattleAxeID", + "sMagicBoundBootsID", + "sMagicBoundCuirassID", + "sMagicBoundDaggerID", + "sMagicBoundHelmID", + "sMagicBoundLeftGauntletID", + "sMagicBoundLongbowID", + "sMagicBoundLongswordID", + "sMagicBoundMaceID", + "sMagicBoundRightGauntletID", + "sMagicBoundShieldID", + "sMagicBoundSpearID", + "sMagicCannotRecast", + "sMagicCenturionSphereID", + "sMagicClannfearID", + "sMagicContractDisease", + "sMagicCorprusWorsens", + "sMagicCreature01ID", + "sMagicCreature02ID", + "sMagicCreature03ID", + "sMagicCreature04ID", + "sMagicCreature05ID", + "sMagicDaedrothID", + "sMagicDremoraID", + "sMagicEffects", + "sMagicFabricantID", + "sMagicFlameAtronachID", + "sMagicFrostAtronachID", + "sMagicGoldenSaintID", + "sMagicGreaterBonewalkerID", + "sMagicHungerID", + "sMagicInsufficientCharge", + "sMagicInsufficientSP", + "sMagicInvalidEffect", + "sMagicInvalidTarget", + "sMagicItem", + "sMagicLeastBonewalkerID", + "sMagicLockSuccess", + "sMagicMenu", + "sMagicOpenSuccess", + "sMagicPCResisted", + "sMagicScampID", + "sMagicSelectTitle", + "sMagicSkeletalMinionID", + "sMagicSkillFail", + "sMagicStormAtronachID", + "sMagicTab", + "sMagicTargetResisted", + "sMagicTargetResistsWeapons", + "sMagicWingedTwilightID", + "sMagnitude", + "sMagnitudeDes", + "sMake", + "sMap", + "sMaster", + "sMastPlugMismatchMsg", + "sMaximumSaveGameMessage", + "sMaxSale", + "sMedium", + "sMenu_Help_Delay", + "sMenu_Mode", + "sMenuModeXbox", + "sMenuNextXbox", + "sMenuPrevXbox", + "sMenus", + "sMessage1", + "sMessage2", + "sMessage3", + "sMessage4", + "sMessage5", + "sMessageQuestionAnswer1", + "sMessageQuestionAnswer2", + "sMessageQuestionAnswer3", + "sMiscTab", + "sMissingMastersMsg", + "sMonk", + "sMonthEveningstar", + "sMonthFirstseed", + "sMonthFrostfall", + "sMonthHeartfire", + "sMonthLastseed", + "sMonthMidyear", + "sMonthMorningstar", + "sMonthRainshand", + "sMonthSecondseed", + "sMonthSunsdawn", + "sMonthSunsdusk", + "sMonthSunsheight", + "sMore", + "sMortar", + "sMouse", + "sMouseFlip", + "sMouseWheelDownShort", + "sMouseWheelUpShort", + "sMove", + "sMoveDownXbox", + "sMoveUpXbox", + "sMusic", + "sName", + "sNameTitle", + "sNear", + "sNeedOneSkill", + "sNeedTwoSkills", + "sNewGame", + "sNext", + "sNextRank", + "sNextSpell", + "sNextSpellXbox", + "sNextWeapon", + "sNextWeaponXbox", + "sNightblade", + "sNo", + "sNoName", + "sNone", + "sNotifyMessage1", + "sNotifyMessage10", + "sNotifyMessage11", + "sNotifyMessage12", + "sNotifyMessage13", + "sNotifyMessage14", + "sNotifyMessage15", + "sNotifyMessage16", + "sNotifyMessage16_a", + "sNotifyMessage17", + "sNotifyMessage18", + "sNotifyMessage19", + "sNotifyMessage2", + "sNotifyMessage20", + "sNotifyMessage21", + "sNotifyMessage22", + "sNotifyMessage23", + "sNotifyMessage24", + "sNotifyMessage25", + "sNotifyMessage26", + "sNotifyMessage27", + "sNotifyMessage28", + "sNotifyMessage29", + "sNotifyMessage3", + "sNotifyMessage30", + "sNotifyMessage31", + "sNotifyMessage32", + "sNotifyMessage33", + "sNotifyMessage34", + "sNotifyMessage35", + "sNotifyMessage36", + "sNotifyMessage37", + "sNotifyMessage38", + "sNotifyMessage39", + "sNotifyMessage4", + "sNotifyMessage40", + "sNotifyMessage41", + "sNotifyMessage42", + "sNotifyMessage43", + "sNotifyMessage44", + "sNotifyMessage45", + "sNotifyMessage46", + "sNotifyMessage47", + "sNotifyMessage48", + "sNotifyMessage49", + "sNotifyMessage4XBOX", + "sNotifyMessage5", + "sNotifyMessage50", + "sNotifyMessage51", + "sNotifyMessage52", + "sNotifyMessage53", + "sNotifyMessage54", + "sNotifyMessage55", + "sNotifyMessage56", + "sNotifyMessage57", + "sNotifyMessage58", + "sNotifyMessage59", + "sNotifyMessage6", + "sNotifyMessage60", + "sNotifyMessage61", + "sNotifyMessage62", + "sNotifyMessage63", + "sNotifyMessage64", + "sNotifyMessage65", + "sNotifyMessage66", + "sNotifyMessage67", + "sNotifyMessage6a", + "sNotifyMessage7", + "sNotifyMessage8", + "sNotifyMessage9", + "sOff", + "sOffer", + "sOfferMenuTitle", + "sOK", + "sOn", + "sOnce", + "sOneHanded", + "sOnetypeEffectMessage", + "sonword", + "sOptions", + "sOptionsMenuXbox", + "spercent", + "sPerDesc", + "sPersuasion", + "sPersuasionMenuTitle", + "sPickUp", + "sPilgrim", + "spoint", + "spoints", + "sPotionSuccess", + "sPowerAlreadyUsed", + "sPowers", + "sPreferences", + "sPrefs", + "sPrev", + "sPrevSpell", + "sPrevSpellXbox", + "sPrevWeapon", + "sPrevWeaponXbox", + "sProfitValue", + "sQuality", + "sQuanityMenuMessage01", + "sQuanityMenuMessage02", + "sQuestionDeleteSpell", + "sQuestionMark", + "sQuick0Xbox", + "sQuick10Cmd", + "sQuick1Cmd", + "sQuick2Cmd", + "sQuick3Cmd", + "sQuick4Cmd", + "sQuick4Xbox", + "sQuick5Cmd", + "sQuick5Xbox", + "sQuick6Cmd", + "sQuick6Xbox", + "sQuick7Cmd", + "sQuick7Xbox", + "sQuick8Cmd", + "sQuick8Xbox", + "sQuick9Cmd", + "sQuick9Xbox", + "sQuick_Save", + "sQuickLoadCmd", + "sQuickLoadXbox", + "sQuickMenu", + "sQuickMenu1", + "sQuickMenu2", + "sQuickMenu3", + "sQuickMenu4", + "sQuickMenu5", + "sQuickMenu6", + "sQuickMenuInstruc", + "sQuickMenuTitle", + "sQuickSaveCmd", + "sQuickSaveXbox", + "sRace", + "sRaceMenu1", + "sRaceMenu2", + "sRaceMenu3", + "sRaceMenu4", + "sRaceMenu5", + "sRaceMenu6", + "sRaceMenu7", + "sRacialTraits", + "sRange", + "sRangeDes", + "sRangeSelf", + "sRangeTarget", + "sRangeTouch", + "sReady_Magic", + "sReady_Weapon", + "sReadyItemXbox", + "sReadyMagicXbox", + "sRechargeEnchantment", + "sRender_Distance", + "sRepair", + "sRepairFailed", + "sRepairServiceTitle", + "sRepairSuccess", + "sReputation", + "sResChangeWarning", + "sRest", + "sRestIllegal", + "sRestKey", + "sRestMenu1", + "sRestMenu2", + "sRestMenu3", + "sRestMenu4", + "sRestMenuXbox", + "sRestore", + "sRetort", + "sReturnToGame", + "sRight", + "sRogue", + "sRun", + "sRunXbox", + "sSave", + "sSaveGame", + "sSaveGameDenied", + "sSaveGameFailed", + "sSaveGameNoMemory", + "sSaveGameTooBig", + "sSaveMenu1", + "sSaveMenuHelp01", + "sSaveMenuHelp02", + "sSaveMenuHelp03", + "sSaveMenuHelp04", + "sSaveMenuHelp05", + "sSaveMenuHelp06", + "sSchool", + "sSchoolAlteration", + "sSchoolConjuration", + "sSchoolDestruction", + "sSchoolIllusion", + "sSchoolMysticism", + "sSchoolRestoration", + "sScout", + "sScrolldown", + "sScrollup", + "ssecond", + "sseconds", + "sSeldom", + "sSelect", + "sSell", + "sSellerGold", + "sService", + "sServiceRefusal", + "sServiceRepairTitle", + "sServiceSpellsTitle", + "sServiceTrainingTitle", + "sServiceTrainingWords", + "sServiceTravelTitle", + "sSetValueMessage01", + "sSex", + "sShadows", + "sShadowText", + "sShift", + "sSkill", + "sSkillAcrobatics", + "sSkillAlchemy", + "sSkillAlteration", + "sSkillArmorer", + "sSkillAthletics", + "sSkillAxe", + "sSkillBlock", + "sSkillBluntweapon", + "sSkillClassMajor", + "sSkillClassMinor", + "sSkillClassMisc", + "sSkillConjuration", + "sSkillDestruction", + "sSkillEnchant", + "sSkillHandtohand", + "sSkillHeavyarmor", + "sSkillIllusion", + "sSkillLightarmor", + "sSkillLongblade", + "sSkillMarksman", + "sSkillMaxReached", + "sSkillMediumarmor", + "sSkillMercantile", + "sSkillMysticism", + "sSkillProgress", + "sSkillRestoration", + "sSkillSecurity", + "sSkillShortblade", + "sSkillsMenu1", + "sSkillsMenuReputationHelp", + "sSkillSneak", + "sSkillSpear", + "sSkillSpeechcraft", + "sSkillUnarmored", + "sSlash", + "sSleepInterrupt", + "sSlideLeftXbox", + "sSlideRightXbox", + "sSlow", + "sSorceror", + "sSoulGem", + "sSoulGemsWithSouls", + "sSoultrapSuccess", + "sSpace", + "sSpdDesc", + "sSpecialization", + "sSpecializationCombat", + "sSpecializationMagic", + "sSpecializationMenu1", + "sSpecializationStealth", + "sSpellmaking", + "sSpellmakingHelp1", + "sSpellmakingHelp2", + "sSpellmakingHelp3", + "sSpellmakingHelp4", + "sSpellmakingHelp5", + "sSpellmakingHelp6", + "sSpellmakingMenu1", + "sSpellmakingMenuTitle", + "sSpells", + "sSpellServiceTitle", + "sSpellsword", + "sStartCell", + "sStartCellError", + "sStartError", + "sStats", + "sStrafe", + "sStrDesc", + "sStrip", + "sSubtitles", + "sSystemMenuXbox", + "sTake", + "sTakeAll", + "sTargetCriticalStrike", + "sTaunt", + "sTauntFail", + "sTauntSuccess", + "sTeleportDisabled", + "sThief", + "sThrust", + "sTo", + "sTogglePOVCmd", + "sTogglePOVXbox", + "sToggleRunXbox", + "sTopics", + "sTotalCost", + "sTotalSold", + "sTraining", + "sTrainingServiceTitle", + "sTraits", + "sTransparency_Menu", + "sTrapFail", + "sTrapImpossible", + "sTrapped", + "sTrapSuccess", + "sTravel", + "sTravelServiceTitle", + "sTurn", + "sTurnLeftXbox", + "sTurnRightXbox", + "sTwoHanded", + "sType", + "sTypeAbility", + "sTypeBlightDisease", + "sTypeCurse", + "sTypeDisease", + "sTypePower", + "sTypeSpell", + "sUnequip", + "sUnlocked", + "sUntilHealed", + "sUse", + "sUserDefinedClass", + "sUses", + "sUseXbox", + "sValue", + "sVideo", + "sVideoWarning", + "sVoice", + "sWait", + "sWarrior", + "sWaterReflectUpdate", + "sWaterTerrainReflect", + "sWeaponTab", + "sWeight", + "sWerewolfAlarmMessage", + "sWerewolfPopup", + "sWerewolfRefusal", + "sWerewolfRestMessage", + "sWilDesc", + "sWitchhunter", + "sWorld", + "sWornTab", + "sXStrafe", + "sXTimes", + "sXTimesINT", + "sYes", + "sYourGold", + 0 + }; + + for (int i=0; gmstFloats[i]; i++) + { + ESM::GameSetting gmst; + gmst.mId = gmstFloats[i]; + gmst.mValue.setType (ESM::VT_Float); + gmst.mValue.setFloat(gmstFloatsValues[i]); + addOptionalGmst (gmst); + } + + for (int i=0; gmstIntegers[i]; i++) + { + ESM::GameSetting gmst; + gmst.mId = gmstIntegers[i]; + gmst.mValue.setType (ESM::VT_Int); + gmst.mValue.setInteger(gmstIntegersValues[i]); + addOptionalGmst (gmst); + } + + for (int i=0; gmstStrings[i]; i++) + { + ESM::GameSetting gmst; + gmst.mId = gmstStrings[i]; + gmst.mValue.setType (ESM::VT_String); + gmst.mValue.setString (""); + addOptionalGmst (gmst); + } +} + void CSMDoc::Document::addOptionalGmsts() { static const char *sFloats[] = @@ -185,7 +2109,15 @@ void CSMDoc::Document::createBase() { static const char *sGlobals[] = { - "Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0 + "Day", + "DaysPassed", + "GameHour", + "Month", + "PCRace", + "PCVampire", + "PCWerewolf", + "PCYear", + 0 }; for (int i=0; sGlobals[i]; ++i) @@ -202,7 +2134,7 @@ void CSMDoc::Document::createBase() getData().getGlobals().add (record); } - /// \todo add GMSTs + addBaseGmsts(); for (int i=0; i<27; ++i) { @@ -247,13 +2179,14 @@ CSMDoc::Document::Document (const std::vector& files, b connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mTools, SIGNAL (done (int)), this, SLOT (operationDone (int))); - // dummy implementation -> remove when proper save is implemented. + // dummy implementation -> remove when proper save is implemented. mSaveCount = 0; connect (&mSaveTimer, SIGNAL(timeout()), this, SLOT (saving())); } CSMDoc::Document::~Document() -{} +{ +} QUndoStack& CSMDoc::Document::getUndoStack() { diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 94d5fe85c..a520d572c 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -52,6 +52,8 @@ namespace CSMDoc void createBase(); + void addBaseGmsts(); + void addOptionalGmsts(); void addOptionalGlobals(); From a1fea97c3ba175307bea2a85c8a2ef3a017c6625 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 03:49:30 +0200 Subject: [PATCH 175/213] use SDL for resolution -> multimonitor support --- apps/launcher/CMakeLists.txt | 1 + apps/launcher/graphicspage.cpp | 132 ++++++++++++++++++++++++++++++--- apps/launcher/graphicspage.hpp | 20 ++++- apps/launcher/main.cpp | 5 ++ apps/launcher/maindialog.cpp | 4 +- files/ui/graphicspage.ui | 10 +++ 6 files changed, 158 insertions(+), 14 deletions(-) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 0c93474da..bff26b63c 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -90,6 +90,7 @@ target_link_libraries(omwlauncher ${Boost_LIBRARIES} ${OGRE_LIBRARIES} ${OGRE_STATIC_PLUGINS} + ${SDL2_LIBRARY} ${QT_LIBRARIES} components ) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index d9e10e764..49f7ef7c4 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -42,6 +43,7 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&))); connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int))); connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool))); + connect(screenComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(screenChanged(const QString&))); } @@ -144,17 +146,84 @@ bool GraphicsPage::setupOgre() } antiAliasingComboBox->clear(); - resolutionComboBox->clear(); antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); - resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem)); - // Load the rest of the values - loadSettings(); return true; } -void GraphicsPage::loadSettings() +bool GraphicsPage::setupSDL() { + // FIXME: do setupSDLWordaround here instead. + // seems like Qt, SDL and Ogre don't like each other + // results in a segfault if SDL is initialized after Qt + + QStringList screens; + for (int i = 0; i < mScreenCount; i++) + { + screens.append(QString("Screen ") + QString::number(i + 1)); + } + screenComboBox->addItems(screens); + + return true; +} + +std::vector GraphicsPage::mVideoModes; +int GraphicsPage::mScreenCount; + +bool GraphicsPage::setupSDLWordaround() { + if (SDL_Init(SDL_INIT_VIDEO) != 0) + { + std::cout << "SDL_Init failed: " << SDL_GetError() << std::endl; + return false; + } + + SDL_DisplayMode mode; + int displayIndex, modeIndex, displays = SDL_GetNumVideoDisplays(); + mScreenCount = displays; + + if(displays < 0) + { + std::cout << "SDL_GetNumVideoDisplays failed: " << SDL_GetError() << std::endl; + SDL_Quit(); + return false; + } + + for (displayIndex = 0; displayIndex < displays; displayIndex++) + { + int modes = SDL_GetNumDisplayModes(displayIndex); + if(modes < 0) + { + std::cout << "SDL_GetNumDisplayModes failed: " << SDL_GetError() << std::endl; + SDL_Quit(); + return false; + } + for (modeIndex = 0; modeIndex < modes; modeIndex++) + { + if (SDL_GetDisplayMode(displayIndex, modeIndex, &mode) < 0) + { + std::cout << "SDL_GetDisplayMode failed: " << SDL_GetError() << std::endl; + SDL_Quit(); + return false; + } + VideoMode vmode; + vmode.w = mode.w; + vmode.h = mode.h; + vmode.screen = displayIndex; + mVideoModes.push_back(vmode); + } + } + + SDL_Quit(); + return true; +} + +bool GraphicsPage::loadSettings() +{ + if (!setupSDL()) + return false; + if (!setupOgre()) + return false; + if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true")) vSyncCheckBox->setCheckState(Qt::Checked); @@ -168,6 +237,9 @@ void GraphicsPage::loadSettings() QString width = mGraphicsSettings.value(QString("Video/resolution x")); QString height = mGraphicsSettings.value(QString("Video/resolution y")); QString resolution = width + QString(" x ") + height; + QString screen = mGraphicsSettings.value(QString("Video/screen")); + + screenComboBox->setCurrentIndex(screenComboBox->findText(QString("Screen ") + screen)); int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith); @@ -180,6 +252,8 @@ void GraphicsPage::loadSettings() customHeightSpinBox->setValue(height.toInt()); } + + return true; } void GraphicsPage::saveSettings() @@ -205,6 +279,11 @@ void GraphicsPage::saveSettings() mGraphicsSettings.setValue(QString("Video/resolution x"), QString::number(customWidthSpinBox->value())); mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value())); } + + QRegExp screenRe(QString(".*(\\d+)")); + if(screenRe.exactMatch(screenComboBox->currentText())) { + mGraphicsSettings.setValue(QString("Video/screen"), screenRe.cap(1)); + } } QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer) @@ -240,6 +319,33 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy return result; } +#if 1 +QStringList GraphicsPage::getAvailableResolutions(int screen) +{ + QStringList result; + for (std::vector::iterator it = mVideoModes.begin(); it != mVideoModes.end(); it++) + { + VideoMode mode = *it; + if(mode.screen != screen) + continue; + + QString aspect = getAspect(mode.w, mode.h); + QString resolution = QString::number(mode.w) + QString(" x ") + QString::number(mode.h); + + if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) { + resolution.append(tr("\t(Wide ") + aspect + ")"); + + } else if (aspect == QLatin1String("4:3")) { + resolution.append(tr("\t(Standard 4:3)")); + } + + result.append(resolution); + } + return result; +} +#endif + +#if 0 QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer) { QString key("Video Mode"); @@ -288,14 +394,15 @@ QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer) return result; } +#endif QRect GraphicsPage::getMaximumResolution() { - QRect max, res; + QRect max; int i, screens = QApplication::desktop()->screenCount(); for (i = 0; i < screens; i++) { - res = QApplication::desktop()->screenGeometry(i); + QRect res = QApplication::desktop()->screenGeometry(i); if (res.width() > max.width()) max.setWidth(res.width()); if (res.height() > max.height()) @@ -309,10 +416,17 @@ void GraphicsPage::rendererChanged(const QString &renderer) mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString()); antiAliasingComboBox->clear(); - resolutionComboBox->clear(); antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); - resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem)); +} + +void GraphicsPage::screenChanged(const QString &screen) +{ + QRegExp screenRe(QString(".*(\\d+)")); + if(screenRe.exactMatch(screen)) { + resolutionComboBox->clear(); + resolutionComboBox->addItems(getAvailableResolutions(screenRe.cap(1).toInt() - 1)); + } } void GraphicsPage::slotFullScreenChanged(int state) diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index 37f56d2bb..5ed4e5632 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -18,6 +18,13 @@ #include "ui_graphicspage.h" +struct VideoMode +{ + int w; + int h; + int screen; +}; + class GraphicsSettings; namespace Files { struct ConfigurationManager; } @@ -30,10 +37,14 @@ public: GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0); void saveSettings(); - bool setupOgre(); + bool loadSettings(); + + // SDL workaround + static bool setupSDLWordaround(); public slots: void rendererChanged(const QString &renderer); + void screenChanged(const QString &screen); private slots: void slotFullScreenChanged(int state); @@ -55,11 +66,14 @@ private: GraphicsSettings &mGraphicsSettings; QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer); - QStringList getAvailableResolutions(Ogre::RenderSystem *renderer); + QStringList getAvailableResolutions(int screen); QRect getMaximumResolution(); - void loadSettings(); + static std::vector mVideoModes; + static int mScreenCount; + bool setupOgre(); + bool setupSDL(); }; #endif diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 09da1d615..e444bb9f2 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -3,9 +3,14 @@ #include #include "maindialog.hpp" +// SDL workaround +#include "graphicspage.hpp" int main(int argc, char *argv[]) { + // SDL woraround + GraphicsPage::setupSDLWordaround(); + QApplication app(argc, argv); // Now we make sure the current dir is set to application path diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 10a3f015a..b75d09c51 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -292,8 +292,8 @@ bool MainDialog::setup() // Now create the pages as they need the settings createPages(); - // Call this so we can exit on Ogre errors before mainwindow is shown - if (!mGraphicsPage->setupOgre()) + // Call this so we can exit on Ogre/SDL errors before mainwindow is shown + if (!mGraphicsPage->loadSettings()) return false; loadSettings(); diff --git a/files/ui/graphicspage.ui b/files/ui/graphicspage.ui index 5c330cebd..7e9fe00d9 100644 --- a/files/ui/graphicspage.ui +++ b/files/ui/graphicspage.ui @@ -58,6 +58,13 @@
+ + + Screen: + + + + Resolution: @@ -71,6 +78,9 @@ + + + From 14d074e3e720343a6aa4a6e4b19d945f800576ab Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 04:21:32 +0200 Subject: [PATCH 176/213] select first screen if none is in the setting --- apps/launcher/graphicspage.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 49f7ef7c4..17a2efc0b 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -239,7 +239,9 @@ bool GraphicsPage::loadSettings() QString resolution = width + QString(" x ") + height; QString screen = mGraphicsSettings.value(QString("Video/screen")); - screenComboBox->setCurrentIndex(screenComboBox->findText(QString("Screen ") + screen)); + int screenIndex = screenComboBox->findText(QString("Screen ") + screen); + if (screenIndex != -1) + screenComboBox->setCurrentIndex(screenIndex); int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith); From bb39a85f164adff8298290ce44fab015317b685b Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 04:43:34 +0200 Subject: [PATCH 177/213] remove double entries --- apps/launcher/graphicspage.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 17a2efc0b..3066a410c 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -205,6 +205,19 @@ bool GraphicsPage::setupSDLWordaround() { SDL_Quit(); return false; } + + bool isDouble = false; + for (std::vector::iterator it = mVideoModes.begin(); it != mVideoModes.end(); it++) + { + if ((*it).w == mode.w && (*it).h == mode.h && (*it).screen == displayIndex) + { + isDouble = true; + break; + } + } + if (isDouble) + continue; + VideoMode vmode; vmode.w = mode.w; vmode.h = mode.h; From 6f7a7b4714144ed3a4487469e53e7e1d4be8f2b7 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 05:02:19 +0200 Subject: [PATCH 178/213] remove old code --- apps/launcher/graphicspage.cpp | 53 ---------------------------------- 1 file changed, 53 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 3066a410c..4594fb4eb 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -334,7 +334,6 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy return result; } -#if 1 QStringList GraphicsPage::getAvailableResolutions(int screen) { QStringList result; @@ -358,58 +357,6 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) } return result; } -#endif - -#if 0 -QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer) -{ - QString key("Video Mode"); - QStringList result; - - uint row = 0; - Ogre::ConfigOptionMap options = renderer->getConfigOptions(); - - for (Ogre::ConfigOptionMap::iterator i = options.begin (); i != options.end (); i++, row++) - { - if (key.toStdString() != i->first) - continue; - - Ogre::StringVector::iterator opt_it; - uint idx = 0; - - for (opt_it = i->second.possibleValues.begin (); - opt_it != i->second.possibleValues.end (); opt_it++, idx++) - { - QRegExp resolutionRe(QString("(\\d+) x (\\d+).*")); - QString resolution = QString::fromStdString(*opt_it).simplified(); - - if (resolutionRe.exactMatch(resolution)) { - - int width = resolutionRe.cap(1).toInt(); - int height = resolutionRe.cap(2).toInt(); - - QString aspect = getAspect(width, height); - QString cleanRes = resolutionRe.cap(1) + QString(" x ") + resolutionRe.cap(2); - - if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) { - cleanRes.append(tr("\t(Wide ") + aspect + ")"); - - } else if (aspect == QLatin1String("4:3")) { - cleanRes.append(tr("\t(Standard 4:3)")); - } - // do not add duplicate resolutions - if (!result.contains(cleanRes)) - result.append(cleanRes); - } - } - } - - // Sort the resolutions in descending order - qSort(result.begin(), result.end(), naturalSortGreaterThanCI); - - return result; -} -#endif QRect GraphicsPage::getMaximumResolution() { From dbfc39468b3511987cee47e531f00aa8ba92c7d4 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 20:45:24 +0200 Subject: [PATCH 179/213] better workaround --- apps/launcher/graphicspage.cpp | 102 +++++++++++---------------------- apps/launcher/graphicspage.hpp | 13 ----- apps/launcher/main.cpp | 12 +++- 3 files changed, 43 insertions(+), 84 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 615b389d2..ad3b2493a 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -153,80 +153,19 @@ bool GraphicsPage::setupOgre() bool GraphicsPage::setupSDL() { - // FIXME: do setupSDLWordaround here instead. - // seems like Qt, SDL and Ogre don't like each other - // results in a segfault if SDL is initialized after Qt - - QStringList screens; - for (int i = 0; i < mScreenCount; i++) - { - screens.append(QString("Screen ") + QString::number(i + 1)); - } - screenComboBox->addItems(screens); - - return true; -} - -std::vector GraphicsPage::mVideoModes; -int GraphicsPage::mScreenCount; - -bool GraphicsPage::setupSDLWordaround() { - if (SDL_Init(SDL_INIT_VIDEO) != 0) - { - std::cout << "SDL_Init failed: " << SDL_GetError() << std::endl; - return false; - } - - SDL_DisplayMode mode; - int displayIndex, modeIndex, displays = SDL_GetNumVideoDisplays(); - mScreenCount = displays; + int displays = SDL_GetNumVideoDisplays(); if(displays < 0) { - std::cout << "SDL_GetNumVideoDisplays failed: " << SDL_GetError() << std::endl; - SDL_Quit(); + qDebug() << "SDL_GetNumVideoDisplays failed: " << QString::fromStdString(SDL_GetError()); return false; } - for (displayIndex = 0; displayIndex < displays; displayIndex++) + for (int i = 0; i < displays; i++) { - int modes = SDL_GetNumDisplayModes(displayIndex); - if(modes < 0) - { - std::cout << "SDL_GetNumDisplayModes failed: " << SDL_GetError() << std::endl; - SDL_Quit(); - return false; - } - for (modeIndex = 0; modeIndex < modes; modeIndex++) - { - if (SDL_GetDisplayMode(displayIndex, modeIndex, &mode) < 0) - { - std::cout << "SDL_GetDisplayMode failed: " << SDL_GetError() << std::endl; - SDL_Quit(); - return false; - } - - bool isDouble = false; - for (std::vector::iterator it = mVideoModes.begin(); it != mVideoModes.end(); it++) - { - if ((*it).w == mode.w && (*it).h == mode.h && (*it).screen == displayIndex) - { - isDouble = true; - break; - } - } - if (isDouble) - continue; - - VideoMode vmode; - vmode.w = mode.w; - vmode.h = mode.h; - vmode.screen = displayIndex; - mVideoModes.push_back(vmode); - } + screenComboBox->addItem(QString("Screen ") + QString::number(i + 1)); } - SDL_Quit(); return true; } @@ -337,10 +276,35 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy QStringList GraphicsPage::getAvailableResolutions(int screen) { QStringList result; - for (std::vector::iterator it = mVideoModes.begin(); it != mVideoModes.end(); it++) + SDL_DisplayMode mode; + int modeIndex, modes = SDL_GetNumDisplayModes(screen); + + if(modes < 0) + { + qDebug() << "SDL_GetNumDisplayModes failed: " << QString::fromStdString(SDL_GetError()); + return result; + } + + QList resolutions; + for (modeIndex = 0; modeIndex < modes; modeIndex++) { - VideoMode mode = *it; - if(mode.screen != screen) + if (SDL_GetDisplayMode(screen, modeIndex, &mode) < 0) + { + qDebug() << "SDL_GetDisplayMode failed: " << QString::fromStdString(SDL_GetError()); + return result; + } + + bool isDuplicate = false; + for (int i = 0; i < resolutions.count(); i++) + { + SDL_DisplayMode omode = resolutions.at(i); + if (omode.w == mode.w && omode.h == mode.h) + { + isDuplicate = true; + break; + } + } + if (isDuplicate) continue; QString aspect = getAspect(mode.w, mode.h); @@ -353,8 +317,10 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) resolution.append(tr("\t(Standard 4:3)")); } + resolutions.append(mode); result.append(resolution); } + return result; } diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index 5ed4e5632..07330f193 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -18,13 +18,6 @@ #include "ui_graphicspage.h" -struct VideoMode -{ - int w; - int h; - int screen; -}; - class GraphicsSettings; namespace Files { struct ConfigurationManager; } @@ -39,9 +32,6 @@ public: void saveSettings(); bool loadSettings(); - // SDL workaround - static bool setupSDLWordaround(); - public slots: void rendererChanged(const QString &renderer); void screenChanged(const QString &screen); @@ -69,9 +59,6 @@ private: QStringList getAvailableResolutions(int screen); QRect getMaximumResolution(); - static std::vector mVideoModes; - static int mScreenCount; - bool setupOgre(); bool setupSDL(); }; diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index e444bb9f2..c6df5a909 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "maindialog.hpp" // SDL workaround @@ -8,8 +9,11 @@ int main(int argc, char *argv[]) { - // SDL woraround - GraphicsPage::setupSDLWordaround(); + if (SDL_Init(SDL_INIT_VIDEO) != 0) + { + qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError()); + return false; + } QApplication app(argc, argv); @@ -46,6 +50,8 @@ int main(int argc, char *argv[]) return 0; } - return app.exec(); + int returnValue = app.exec(); + SDL_Quit(); + return returnValue; } From 6abb5d5f751d4fd0bc2077a58808c691d21ceab7 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 20:53:50 +0200 Subject: [PATCH 180/213] small fixes --- apps/launcher/graphicspage.cpp | 8 ++++---- apps/launcher/main.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index ad3b2493a..b185b3cd2 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -155,7 +155,7 @@ bool GraphicsPage::setupSDL() { int displays = SDL_GetNumVideoDisplays(); - if(displays < 0) + if (displays < 0) { qDebug() << "SDL_GetNumVideoDisplays failed: " << QString::fromStdString(SDL_GetError()); return false; @@ -235,7 +235,7 @@ void GraphicsPage::saveSettings() } QRegExp screenRe(QString(".*(\\d+)")); - if(screenRe.exactMatch(screenComboBox->currentText())) { + if (screenRe.exactMatch(screenComboBox->currentText())) { mGraphicsSettings.setValue(QString("Video/screen"), screenRe.cap(1)); } } @@ -279,7 +279,7 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) SDL_DisplayMode mode; int modeIndex, modes = SDL_GetNumDisplayModes(screen); - if(modes < 0) + if (modes < 0) { qDebug() << "SDL_GetNumDisplayModes failed: " << QString::fromStdString(SDL_GetError()); return result; @@ -351,7 +351,7 @@ void GraphicsPage::rendererChanged(const QString &renderer) void GraphicsPage::screenChanged(const QString &screen) { QRegExp screenRe(QString(".*(\\d+)")); - if(screenRe.exactMatch(screen)) { + if (screenRe.exactMatch(screen)) { resolutionComboBox->clear(); resolutionComboBox->addItems(getAvailableResolutions(screenRe.cap(1).toInt() - 1)); } diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index c6df5a909..5537bdb1a 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -12,7 +12,7 @@ int main(int argc, char *argv[]) if (SDL_Init(SDL_INIT_VIDEO) != 0) { qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError()); - return false; + return 0; } QApplication app(argc, argv); From 89dee80dcff9b726d8132f74a6e0754d3338ee61 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 21:04:49 +0200 Subject: [PATCH 181/213] simpler remove of duplicates --- apps/launcher/graphicspage.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index b185b3cd2..333dff121 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -285,7 +285,6 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) return result; } - QList resolutions; for (modeIndex = 0; modeIndex < modes; modeIndex++) { if (SDL_GetDisplayMode(screen, modeIndex, &mode) < 0) @@ -294,19 +293,6 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) return result; } - bool isDuplicate = false; - for (int i = 0; i < resolutions.count(); i++) - { - SDL_DisplayMode omode = resolutions.at(i); - if (omode.w == mode.w && omode.h == mode.h) - { - isDuplicate = true; - break; - } - } - if (isDuplicate) - continue; - QString aspect = getAspect(mode.w, mode.h); QString resolution = QString::number(mode.w) + QString(" x ") + QString::number(mode.h); @@ -317,10 +303,10 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) resolution.append(tr("\t(Standard 4:3)")); } - resolutions.append(mode); result.append(resolution); } + result.removeDuplicates(); return result; } From c97fac811699b754174eedb49b7aed517afd4266 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 21:16:51 +0200 Subject: [PATCH 182/213] use QMessageBox to show errors --- apps/launcher/graphicspage.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 333dff121..f6550f2a1 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -157,7 +157,12 @@ bool GraphicsPage::setupSDL() if (displays < 0) { - qDebug() << "SDL_GetNumVideoDisplays failed: " << QString::fromStdString(SDL_GetError()); + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error receiving number of screens")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
SDL_GetNumDisplayModes failed:

") + QString::fromStdString(SDL_GetError()) + "
"); + msgBox.exec(); return false; } @@ -281,7 +286,12 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) if (modes < 0) { - qDebug() << "SDL_GetNumDisplayModes failed: " << QString::fromStdString(SDL_GetError()); + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error receiving resolutions")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
SDL_GetNumDisplayModes failed:

") + QString::fromStdString(SDL_GetError()) + "
"); + msgBox.exec(); return result; } @@ -289,7 +299,12 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) { if (SDL_GetDisplayMode(screen, modeIndex, &mode) < 0) { - qDebug() << "SDL_GetDisplayMode failed: " << QString::fromStdString(SDL_GetError()); + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error receiving resolutions")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
SDL_GetDisplayMode failed:

") + QString::fromStdString(SDL_GetError()) + "
"); + msgBox.exec(); return result; } From 58037262330a376caa8a9f3868d06411459e9ef8 Mon Sep 17 00:00:00 2001 From: mckibbenta Date: Sun, 23 Jun 2013 15:19:08 -0400 Subject: [PATCH 183/213] modified gmst addition during creation of new base file --- apps/opencs/model/doc/document.cpp | 16 +++++++--------- apps/opencs/model/doc/document.hpp | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 369331244..6722e196b 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -24,7 +24,7 @@ void CSMDoc::Document::load (const std::vector::const_i getData().loadFile (*end2, false); } -void CSMDoc::Document::addBaseGmsts() +void CSMDoc::Document::addGmsts() { static const char *gmstFloats[] = { @@ -1922,8 +1922,8 @@ void CSMDoc::Document::addBaseGmsts() ESM::GameSetting gmst; gmst.mId = gmstFloats[i]; gmst.mValue.setType (ESM::VT_Float); - gmst.mValue.setFloat(gmstFloatsValues[i]); - addOptionalGmst (gmst); + gmst.mValue.setFloat (gmstFloatsValues[i]); + getData().getGmsts().add (gmst); } for (int i=0; gmstIntegers[i]; i++) @@ -1931,8 +1931,8 @@ void CSMDoc::Document::addBaseGmsts() ESM::GameSetting gmst; gmst.mId = gmstIntegers[i]; gmst.mValue.setType (ESM::VT_Int); - gmst.mValue.setInteger(gmstIntegersValues[i]); - addOptionalGmst (gmst); + gmst.mValue.setInteger (gmstIntegersValues[i]); + getData().getGmsts().add (gmst); } for (int i=0; gmstStrings[i]; i++) @@ -1941,7 +1941,7 @@ void CSMDoc::Document::addBaseGmsts() gmst.mId = gmstStrings[i]; gmst.mValue.setType (ESM::VT_String); gmst.mValue.setString (""); - addOptionalGmst (gmst); + getData().getGmsts().add (gmst); } } @@ -2123,9 +2123,7 @@ void CSMDoc::Document::createBase() for (int i=0; sGlobals[i]; ++i) { ESM::Global record; - record.mId = sGlobals[i]; - record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Long); if (i==0 || i==1) @@ -2134,7 +2132,7 @@ void CSMDoc::Document::createBase() getData().getGlobals().add (record); } - addBaseGmsts(); + addGmsts(); for (int i=0; i<27; ++i) { diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index a520d572c..1c6d9db2a 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -52,7 +52,7 @@ namespace CSMDoc void createBase(); - void addBaseGmsts(); + void addGmsts(); void addOptionalGmsts(); From 357974a4291f4b7a8de63654731283187007e1b0 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 21:34:41 +0200 Subject: [PATCH 184/213] more minor stuff --- apps/launcher/main.cpp | 1 + files/settings-default.cfg | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 5537bdb1a..414e1a003 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -9,6 +9,7 @@ int main(int argc, char *argv[]) { + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); if (SDL_Init(SDL_INIT_VIDEO) != 0) { qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError()); diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 69aa20883..1819ebb0a 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -6,6 +6,7 @@ resolution x = 800 resolution y = 600 fullscreen = false +screen = 1 # Render system # blank means default From 20e591fe187e61c64dcab4b37854c980165701f0 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 21:56:27 +0200 Subject: [PATCH 185/213] use index instead of string manipulation --- apps/launcher/graphicspage.cpp | 20 +++++++------------- apps/launcher/graphicspage.hpp | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index f6550f2a1..1bbf7f897 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -43,7 +43,7 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&))); connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int))); connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool))); - connect(screenComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(screenChanged(const QString&))); + connect(screenComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(screenChanged(int))); } @@ -168,7 +168,7 @@ bool GraphicsPage::setupSDL() for (int i = 0; i < displays; i++) { - screenComboBox->addItem(QString("Screen ") + QString::number(i + 1)); + screenComboBox->addItem(QString(tr("Screen ")) + QString::number(i + 1)); } return true; @@ -196,9 +196,7 @@ bool GraphicsPage::loadSettings() QString resolution = width + QString(" x ") + height; QString screen = mGraphicsSettings.value(QString("Video/screen")); - int screenIndex = screenComboBox->findText(QString("Screen ") + screen); - if (screenIndex != -1) - screenComboBox->setCurrentIndex(screenIndex); + screenComboBox->setCurrentIndex(screen.toInt()); int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith); @@ -239,10 +237,7 @@ void GraphicsPage::saveSettings() mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value())); } - QRegExp screenRe(QString(".*(\\d+)")); - if (screenRe.exactMatch(screenComboBox->currentText())) { - mGraphicsSettings.setValue(QString("Video/screen"), screenRe.cap(1)); - } + mGraphicsSettings.setValue(QString("Video/screen"), QString::number(screenComboBox->currentIndex())); } QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer) @@ -349,12 +344,11 @@ void GraphicsPage::rendererChanged(const QString &renderer) antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); } -void GraphicsPage::screenChanged(const QString &screen) +void GraphicsPage::screenChanged(int screen) { - QRegExp screenRe(QString(".*(\\d+)")); - if (screenRe.exactMatch(screen)) { + if (screen >= 0) { resolutionComboBox->clear(); - resolutionComboBox->addItems(getAvailableResolutions(screenRe.cap(1).toInt() - 1)); + resolutionComboBox->addItems(getAvailableResolutions(screen)); } } diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index 07330f193..d233ea12e 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -34,7 +34,7 @@ public: public slots: void rendererChanged(const QString &renderer); - void screenChanged(const QString &screen); + void screenChanged(int screen); private slots: void slotFullScreenChanged(int state); From 99508a6eaa10e60078b4fec8823c908613863813 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 23 Jun 2013 22:52:02 +0200 Subject: [PATCH 186/213] minor cleanup --- apps/opencs/model/doc/document.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 6722e196b..07cc32465 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -3,10 +3,6 @@ #include -#include - -#include - void CSMDoc::Document::load (const std::vector::const_iterator& begin, const std::vector::const_iterator& end, bool lastAsModified) { @@ -738,7 +734,7 @@ void CSMDoc::Document::addGmsts() 20, // iWereWolfLevelToAttack }; - static const char *gmstStrings[] = + static const char *gmstStrings[] = { "s3dAudio", "s3dHardware", From b6dd9ae3371d954c8021a7307b7f1dd8a3c4129c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 23 Jun 2013 22:52:50 +0200 Subject: [PATCH 187/213] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 1f7c94e7f..30cfc7e57 100644 --- a/credits.txt +++ b/credits.txt @@ -12,6 +12,7 @@ Marc Zinnschlag (Zini) - Lead Programmer/Project Manager Adam Hogan (aurix) Aleksandar Jovanov +Alex McKibben (WeirdSexy) Alexander Nadeau (wareya) Alexander Olofsson (Ace) Artem Kotsynyak (greye) From acaba78a11ce8f9fe9d5b3fa381fa5a75473e80a Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 23 Jun 2013 23:13:54 +0200 Subject: [PATCH 188/213] wrong number --- files/settings-default.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 1819ebb0a..613f12432 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -6,7 +6,7 @@ resolution x = 800 resolution y = 600 fullscreen = false -screen = 1 +screen = 0 # Render system # blank means default From 09cca0bf80e4429cd5d23226576eb79a06da067f Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 23 Jun 2013 16:45:23 -0700 Subject: [PATCH 189/213] more detailed error message when SDL fails to initialize --- apps/openmw/engine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 6c7247845..c0b212550 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -152,7 +152,9 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) //might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ? SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); if(SDL_Init(flags) != 0) - throw std::runtime_error("Couldn't initialize SDL!"); + { + throw std::runtime_error("Could not initialize SDL! " + std::string(SDL_GetError())); + } } } From 7175c7cfe0330f88660378aab65a6a30456c9a22 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 23 Jun 2013 21:17:52 -0500 Subject: [PATCH 190/213] Updated OpenMW project CMakeLists.txt to include opencs.cfg file installation. --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f86d92aef..ce29e66f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -297,9 +297,12 @@ configure_file(${OpenMW_SOURCE_DIR}/files/transparency-overrides.cfg configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local "${OpenMW_BINARY_DIR}/openmw.cfg") + configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg "${OpenMW_BINARY_DIR}/openmw.cfg.install") +configure_file(${OpenMW_SOURCE_DIR}/files/opencs.cfg + "${OpenMW_BINARY_DIR}/opencs.cfg") if (NOT WIN32 AND NOT APPLE) configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop @@ -344,6 +347,7 @@ if(DPKG_PROGRAM) 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}/transparency-overrides.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}/opencs.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") #Install resources INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "share/games/openmw/" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources") @@ -582,6 +586,7 @@ if (APPLE) install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) + install(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) set(CPACK_GENERATOR "DragNDrop") set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) @@ -697,6 +702,7 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE) #INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${SYSCONFDIR}" ) INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" ) INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" ) + INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "${SYSCONFDIR}" ) # Install resources INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" ) From 8f4fd8202e009b8c483d171df1358cedea54f437 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 23 Jun 2013 21:28:58 -0500 Subject: [PATCH 191/213] Deleted ".directory" text files. Files were hidden files added by dolphin. --- files/opencs.cfg | 5 +++++ files/opencs/raster/.directory | 5 ----- files/opencs/scalable/top-level/.directory | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) create mode 100644 files/opencs.cfg delete mode 100644 files/opencs/raster/.directory delete mode 100644 files/opencs/scalable/top-level/.directory diff --git a/files/opencs.cfg b/files/opencs.cfg new file mode 100644 index 000000000..3faac7c8e --- /dev/null +++ b/files/opencs.cfg @@ -0,0 +1,5 @@ +[Editor] +Record Status Display = Icon and Text +[Window Size] +Width = 640 +Height = 480 diff --git a/files/opencs/raster/.directory b/files/opencs/raster/.directory deleted file mode 100644 index 7a78deef5..000000000 --- a/files/opencs/raster/.directory +++ /dev/null @@ -1,5 +0,0 @@ -[Dolphin] -PreviewsShown=true -Timestamp=2013,3,31,10,12,5 -Version=3 -ViewMode=1 diff --git a/files/opencs/scalable/top-level/.directory b/files/opencs/scalable/top-level/.directory deleted file mode 100644 index 464bddbfc..000000000 --- a/files/opencs/scalable/top-level/.directory +++ /dev/null @@ -1,5 +0,0 @@ -[Dolphin] -PreviewsShown=true -Timestamp=2013,4,3,11,19,41 -Version=3 -ViewMode=1 From d75391de8ef504a9ec6ec041a52e7822dcdcf55d Mon Sep 17 00:00:00 2001 From: eroen Date: Mon, 24 Jun 2013 21:08:29 +0200 Subject: [PATCH 192/213] libav-9 - fix missing includes With libav-9 and ffmpeg-1.0, libavcodec/avcodec.h no longer defines the AV_CH_LAYOUT_* constants. They have been defined in libavutil/channel_layout.h for a long time prior to this. --- apps/openmw/mwrender/videoplayer.cpp | 8 ++++++++ apps/openmw/mwsound/ffmpeg_decoder.hpp | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 1b5eddc21..7e344d1d9 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -42,6 +42,14 @@ extern "C" #if AV_VERSION_INT(55, 0, 100) <= AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO) #include #endif + + // From libavcodec version 54.0.0 and onward the declaration of + // AV_CH_LAYOUT_* is removed from libavcodec/avcodec.h and moved to + // libavutil/channel_layout.h + #if AV_VERSION_INT(54, 0, 0) <= AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) + #include + #endif } #define MAX_AUDIOQ_SIZE (5 * 16 * 1024) diff --git a/apps/openmw/mwsound/ffmpeg_decoder.hpp b/apps/openmw/mwsound/ffmpeg_decoder.hpp index a5e5b5083..8df6aca67 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.hpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.hpp @@ -10,6 +10,14 @@ extern "C" { #include #include + +// From libavcodec version 54.0.0 and onward the declaration of +// AV_CH_LAYOUT_* is removed from libavcodec/avcodec.h and moved to +// libavutil/channel_layout.h +#if AV_VERSION_INT(54, 0, 0) <= AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) + #include +#endif } #include From 0a2ed8b0d7a2827c4d042f2e737f803c36c41fc4 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Tue, 25 Jun 2013 15:05:10 +0200 Subject: [PATCH 193/213] Make OpenMW able to initialize SDL in windows builds --- apps/openmw/CMakeLists.txt | 1 + apps/openmw/main.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index ddb08f0b0..501e5c5ae 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -112,6 +112,7 @@ target_link_libraries(openmw ${BULLET_LIBRARIES} ${MYGUI_LIBRARIES} ${SDL2_LIBRARY} + ${SDL2MAIN_LIBRARY} ${MYGUI_PLATFORM_LIBRARIES} ${SHINY_LIBRARIES} "oics" diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index a68c89683..f11d153b4 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -2,6 +2,7 @@ #include +#include #include "engine.hpp" #if defined(_WIN32) && !defined(_CONSOLE) From f0f895ad1022b9ba7b5c27306f8c683d92f4c397 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 25 Jun 2013 19:32:36 -0500 Subject: [PATCH 194/213] Fixed settings file error message Errors only occur if both global and local settings files are not found. All other file read errors fail silently. --- apps/opencs/model/settings/usersettings.cpp | 108 ++++++++++++-------- apps/opencs/model/settings/usersettings.hpp | 6 +- 2 files changed, 69 insertions(+), 45 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index c17f28d4e..508942f58 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -61,57 +61,49 @@ QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, else openFlags = QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate; - if (!(file->open(openFlags))) - { - // File cannot be opened or created - QMessageBox msgBox; - msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - - QString fileMessage = QObject::tr("
File: %0").arg(file->fileName()); - - if (!isReadOnly) - msgBox.setText (mReadWriteMessage + fileMessage); - else - msgBox.setText (mReadOnlyMessage + fileMessage); - - msgBox.exec(); - delete file; - file = 0; - } - QTextStream *stream = 0; - if (file) + if (file->open(openFlags)) { stream = new QTextStream(file); stream->setCodec(QTextCodec::codecForName("UTF-8")); } + if (!stream) + { + delete file; + file = 0; + } + return stream; } bool CSMSettings::UserSettings::writeSettings(QMap &settings) { - QTextStream *stream = openFileStream(mPaths.back()); + QTextStream *stream = openFileStream(mUserFilePath); - QList keyList = settings.keys(); + if (!stream) + displayFileErrorMessage(mReadWriteMessage, false); - foreach (QString key, keyList) + if (stream) { - SettingList *sectionSettings = settings[key]; + QList keyList = settings.keys(); - *stream << "[" << key << "]" << '\n'; + foreach (QString key, keyList) + { + SettingList *sectionSettings = settings[key]; - foreach (SettingContainer *item, *sectionSettings) - *stream << item->objectName() << " = " << item->getValue() << '\n'; - } + *stream << "[" << key << "]" << '\n'; - stream->device()->close(); + foreach (SettingContainer *item, *sectionSettings) + *stream << item->objectName() << " = " << item->getValue() << '\n'; + } - return true; + stream->device()->close(); + } + + return (stream); } @@ -120,10 +112,10 @@ const CSMSettings::SectionMap &CSMSettings::UserSettings::getSettings() const return mSectionSettings; } -void CSMSettings::UserSettings::loadFromFile(const QString &filePath) +bool CSMSettings::UserSettings::loadFromFile(const QString &filePath) { if (filePath.isEmpty()) - return; + return false; mSectionSettings.clear(); @@ -181,22 +173,37 @@ void CSMSettings::UserSettings::loadFromFile(const QString &filePath) stream->device()->close(); } - return; + return (stream); } void CSMSettings::UserSettings::loadSettings (const QString &fileName) { - if (mPaths.count() == 0) - { - mPaths.append(QString::fromStdString(mCfgMgr.getGlobalPath().string()) + fileName); - mPaths.append(QString::fromStdString(mCfgMgr.getLocalPath().string()) + fileName); - mPaths.append(QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName); - } + bool globalOk; + bool localOk; - foreach (const QString &path, mPaths) + //global + QString globalFilePath = QString::fromStdString(mCfgMgr.getGlobalPath().string()) + fileName; + globalOk = loadFromFile(globalFilePath); + + + //local + QString localFilePath = QString::fromStdString(mCfgMgr.getLocalPath().string()) + fileName; + localOk = loadFromFile(localFilePath); + + //user + mUserFilePath = QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName; + loadFromFile(mUserFilePath); + + if (!(localOk || globalOk)) { - qDebug() << "Loading config file:" << qPrintable(path); - loadFromFile(path); + QString message = QObject::tr("
Could not open user settings files for reading

\ + Global and local settings files could not be read.\ + You may have incorrect file permissions or the OpenCS installation may be corrupted.
"); + + message += QObject::tr("
Global filepath: ") + globalFilePath; + message += QObject::tr("
Local filepath: ") + localFilePath; + + displayFileErrorMessage ( message, true); } } @@ -245,3 +252,18 @@ CSMSettings::UserSettings& CSMSettings::UserSettings::instance() return *mUserSettingsInstance; } +void CSMSettings::UserSettings::displayFileErrorMessage(const QString &message, bool isReadOnly) +{ + // File cannot be opened or created + QMessageBox msgBox; + msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + + if (!isReadOnly) + msgBox.setText (mReadWriteMessage + message); + else + msgBox.setText (message); + + msgBox.exec(); +} diff --git a/apps/opencs/model/settings/usersettings.hpp b/apps/opencs/model/settings/usersettings.hpp index da8408b3e..49b226df9 100644 --- a/apps/opencs/model/settings/usersettings.hpp +++ b/apps/opencs/model/settings/usersettings.hpp @@ -28,7 +28,7 @@ namespace CSMSettings { SectionMap mSectionSettings; static UserSettings *mUserSettingsInstance; - QStringList mPaths; + QString mUserFilePath; Files::ConfigurationManager mCfgMgr; QString mReadOnlyMessage; QString mReadWriteMessage; @@ -70,7 +70,9 @@ namespace CSMSettings { QTextStream *openFileStream (const QString &filePath, bool isReadOnly = false) const; /// Parses a setting file specified in filePath from the provided text stream. - void loadFromFile (const QString &filePath = ""); + bool loadFromFile (const QString &filePath = ""); + + void displayFileErrorMessage(const QString &message, bool isReadOnly); signals: From 743b3dec999ffc718bb132b97ddc619bd93a8bda Mon Sep 17 00:00:00 2001 From: Miroslav Puda Date: Wed, 26 Jun 2013 07:17:29 +0200 Subject: [PATCH 195/213] Correction of libavutil version --- apps/openmw/mwrender/videoplayer.cpp | 6 +++--- apps/openmw/mwsound/ffmpeg_decoder.hpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 7e344d1d9..08642c5a3 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -43,11 +43,11 @@ extern "C" #include #endif - // From libavcodec version 54.0.0 and onward the declaration of + // From libavutil version 52.2.0 and onward the declaration of // AV_CH_LAYOUT_* is removed from libavcodec/avcodec.h and moved to // libavutil/channel_layout.h - #if AV_VERSION_INT(54, 0, 0) <= AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ - LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) + #if AV_VERSION_INT(52, 2, 0) <= AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO) #include #endif } diff --git a/apps/openmw/mwsound/ffmpeg_decoder.hpp b/apps/openmw/mwsound/ffmpeg_decoder.hpp index 8df6aca67..d0d73379d 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.hpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.hpp @@ -11,11 +11,11 @@ extern "C" #include #include -// From libavcodec version 54.0.0 and onward the declaration of +// From libavutil version 52.2.0 and onward the declaration of // AV_CH_LAYOUT_* is removed from libavcodec/avcodec.h and moved to // libavutil/channel_layout.h -#if AV_VERSION_INT(54, 0, 0) <= AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ - LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO) +#if AV_VERSION_INT(52, 2, 0) <= AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO) #include #endif } From 8ffea60b72f86a87aaad511dbef2e7b12e64274a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 26 Jun 2013 10:09:26 +0200 Subject: [PATCH 196/213] some cleanup --- apps/launcher/main.cpp | 2 ++ apps/opencs/view/settings/customblock.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 414e1a003..dfe2d7413 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -1,6 +1,8 @@ #include #include #include +#include + #include #include "maindialog.hpp" diff --git a/apps/opencs/view/settings/customblock.cpp b/apps/opencs/view/settings/customblock.cpp index a07ee5ac9..bbceafabe 100644 --- a/apps/opencs/view/settings/customblock.cpp +++ b/apps/opencs/view/settings/customblock.cpp @@ -40,7 +40,7 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis CSVSettings::GroupBox *CSVSettings::CustomBlock::buildGroupBox (Orientation orientation) { GroupBox *box = new GroupBox (false, mBox); - QLayout *layout = createLayout (orientation, true, box); + createLayout (orientation, true, box); return box; } From f4d302501e9afe07521d919bd75b45f64ada8139 Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 26 Jun 2013 18:29:09 +0200 Subject: [PATCH 197/213] Bugfix #826 --- apps/esmtool/esmtool.cpp | 18 ++++++++++++++---- apps/mwiniimporter/main.cpp | 21 ++++++++++++++++----- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 8e0900ba0..57e9f59cc 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -108,11 +108,21 @@ bool parseOptions (int argc, char** argv, Arguments &info) // there might be a better way to do this bpo::options_description all; all.add(desc).add(hidden); - bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) - .options(all).positional(p).run(); - bpo::variables_map variables; - bpo::store(valid_opts, variables); + + try + { + bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) + .options(all).positional(p).run(); + + bpo::store(valid_opts, variables); + } + catch(boost::program_options::unknown_option & x) + { + std::cerr << "ERROR: " << x.what() << std::endl; + return false; + } + bpo::notify(variables); if (variables.count ("help")) diff --git a/apps/mwiniimporter/main.cpp b/apps/mwiniimporter/main.cpp index 510b0c4a0..9aff898b9 100644 --- a/apps/mwiniimporter/main.cpp +++ b/apps/mwiniimporter/main.cpp @@ -28,12 +28,23 @@ int main(int argc, char *argv[]) { p_desc.add("ini", 1).add("cfg", 1); bpo::variables_map vm; - bpo::parsed_options parsed = bpo::command_line_parser(argc, argv) - .options(desc) - .positional(p_desc) - .run(); - bpo::store(parsed, vm); + try + { + bpo::parsed_options parsed = bpo::command_line_parser(argc, argv) + .options(desc) + .positional(p_desc) + .run(); + + bpo::store(parsed, vm); + } + catch(boost::program_options::unknown_option & x) + { + std::cerr << "ERROR: " << x.what() << std::endl; + return false; + } + + if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) { std::cout << desc; From 5b81d124bba3017f44a890af507a21397b3cbdad Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 26 Jun 2013 18:43:27 +0200 Subject: [PATCH 198/213] Catched another exception --- apps/esmtool/esmtool.cpp | 5 +++++ apps/mwiniimporter/main.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index 57e9f59cc..a60e9f0e2 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -122,6 +122,11 @@ bool parseOptions (int argc, char** argv, Arguments &info) std::cerr << "ERROR: " << x.what() << std::endl; return false; } + catch(boost::program_options::invalid_command_line_syntax & x) + { + std::cerr << "ERROR: " << x.what() << std::endl; + return false; + } bpo::notify(variables); diff --git a/apps/mwiniimporter/main.cpp b/apps/mwiniimporter/main.cpp index 9aff898b9..364a6b1a4 100644 --- a/apps/mwiniimporter/main.cpp +++ b/apps/mwiniimporter/main.cpp @@ -43,8 +43,11 @@ int main(int argc, char *argv[]) { std::cerr << "ERROR: " << x.what() << std::endl; return false; } - - + catch(boost::program_options::invalid_command_line_syntax & x) + { + std::cerr << "ERROR: " << x.what() << std::endl; + return false; + } if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) { std::cout << desc; From 88f8637145d94fdd82be827ace5fb4d1c7c738bb Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 26 Jun 2013 22:20:24 +0200 Subject: [PATCH 199/213] Bugfix #795 --- apps/openmw/mwmechanics/character.cpp | 8 ++++++++ apps/openmw/mwmechanics/character.hpp | 3 +++ 2 files changed, 11 insertions(+) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index aa20e1414..abc6b82c4 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -179,6 +179,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim , mSkipAnim(false) , mSecondsOfRunning(0) , mSecondsOfSwimming(0) + , mUpdateWeapon(true) { if(!mAnimation) return; @@ -407,6 +408,13 @@ void CharacterController::update(float duration, Movement &movement) else weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if(mUpdateWeapon) + { + mWeaponType = weaptype; + forceStateUpdate(); + mUpdateWeapon = false; + } + if(weaptype != mWeaponType) { std::string weapgroup; diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 7067176e0..cf5d6e823 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -104,6 +104,9 @@ class CharacterController WeaponType mWeaponType; bool mSkipAnim; + // Workaround for playing weapon draw animation and sound when going to new cell + bool mUpdateWeapon; + // counted for skill increase float mSecondsOfSwimming; float mSecondsOfRunning; From 6deddf722977d1e11c9f51062a22bcffe5cdede2 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Wed, 26 Jun 2013 21:18:21 -0500 Subject: [PATCH 200/213] Fixed code conventions in user settings, changed top-level page names --- apps/opencs/model/settings/usersettings.cpp | 75 ++++++++++----------- apps/opencs/view/settings/editorpage.cpp | 2 +- apps/opencs/view/settings/windowpage.cpp | 2 +- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 508942f58..b73fbfdf4 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -52,15 +52,14 @@ CSMSettings::UserSettings::~UserSettings() QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, bool isReadOnly) const { - QFile *file = new QFile(filePath); - - QIODevice::OpenMode openFlags; + QIODevice::OpenMode openFlags = QIODevice::Text; if (isReadOnly) - openFlags = QIODevice::ReadOnly | QIODevice::Text; + openFlags = QIODevice::ReadOnly | openFlags; else - openFlags = QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate; + openFlags = QIODevice::ReadWrite | QIODevice::Truncate | openFlags; + QFile *file = new QFile(filePath); QTextStream *stream = 0; if (file->open(openFlags)) @@ -69,12 +68,6 @@ QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, stream->setCodec(QTextCodec::codecForName("UTF-8")); } - if (!stream) - { - delete file; - file = 0; - } - return stream; } @@ -83,10 +76,9 @@ bool CSMSettings::UserSettings::writeSettings(QMap keyList = settings.keys(); @@ -101,9 +93,15 @@ bool CSMSettings::UserSettings::writeSettings(QMapdevice()->close(); + delete stream; + stream = 0; + } + else + { + displayFileErrorMessage(mReadWriteMessage, false); } - return (stream); + return (success); } @@ -121,7 +119,9 @@ bool CSMSettings::UserSettings::loadFromFile(const QString &filePath) QTextStream *stream = openFileStream (filePath, true); - if (stream) + bool success = (stream); + + if (success) { //looks for a square bracket, "'\\[" //that has one or more "not nothing" in it, "([^]]+)" @@ -171,24 +171,23 @@ bool CSMSettings::UserSettings::loadFromFile(const QString &filePath) mSectionSettings.insert(section, settings); stream->device()->close(); + delete stream; + stream = 0; } - return (stream); + return success; } void CSMSettings::UserSettings::loadSettings (const QString &fileName) { - bool globalOk; - bool localOk; - //global QString globalFilePath = QString::fromStdString(mCfgMgr.getGlobalPath().string()) + fileName; - globalOk = loadFromFile(globalFilePath); + bool globalOk = loadFromFile(globalFilePath); //local QString localFilePath = QString::fromStdString(mCfgMgr.getLocalPath().string()) + fileName; - localOk = loadFromFile(localFilePath); + bool localOk = loadFromFile(localFilePath); //user mUserFilePath = QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName; @@ -209,23 +208,21 @@ void CSMSettings::UserSettings::loadSettings (const QString &fileName) void CSMSettings::UserSettings::updateSettings (const QString §ionName, const QString &settingName) { - SettingMap *settings = mSectionSettings[sectionName]; - - if (!settings) + if (mSectionSettings.find(sectionName) == mSectionSettings.end()) return; - SettingContainer *setting = 0; + SettingMap *settings = mSectionSettings.value(sectionName); if (settingName.isEmpty()) { - foreach (setting, *settings) + foreach (const SettingContainer *setting, *settings) emit signalUpdateEditorSetting (setting->objectName(), setting->getValue()); } else { - if (settings->find(settingName)!=settings->end()) + if (settings->find(settingName) != settings->end()) { - setting = settings->value(settingName); + const SettingContainer *setting = settings->value(settingName); emit signalUpdateEditorSetting (setting->objectName(), setting->getValue()); } } @@ -233,23 +230,23 @@ void CSMSettings::UserSettings::updateSettings (const QString §ionName, cons QString CSMSettings::UserSettings::getSetting (const QString §ion, const QString &setting) const { - if(mSectionSettings.find(section) == mSectionSettings.end()) - return QString(); - - CSMSettings::SettingMap *settings = mSectionSettings.value(section); + QString retVal = ""; - if(settings->find(setting) == settings->end()) - return QString(); + if (mSectionSettings.find(section) != mSectionSettings.end()) + { + CSMSettings::SettingMap *settings = mSectionSettings.value(section); - CSMSettings::SettingContainer *settingContainer = settings->value(setting); + if (settings->find(setting) != settings->end()) + retVal = settings->value(setting)->getValue(); + } - return settingContainer->getValue(); + return retVal; } CSMSettings::UserSettings& CSMSettings::UserSettings::instance() { - assert(mUserSettingsInstance); - return *mUserSettingsInstance; + assert(mUserSettingsInstance); + return *mUserSettingsInstance; } void CSMSettings::UserSettings::displayFileErrorMessage(const QString &message, bool isReadOnly) diff --git a/apps/opencs/view/settings/editorpage.cpp b/apps/opencs/view/settings/editorpage.cpp index 50b5a6536..153ac1551 100644 --- a/apps/opencs/view/settings/editorpage.cpp +++ b/apps/opencs/view/settings/editorpage.cpp @@ -3,7 +3,7 @@ #include "../../model/settings/usersettings.hpp" CSVSettings::EditorPage::EditorPage(QWidget* parent) : - AbstractPage("Editor", parent) + AbstractPage("Display Format", parent) { setupUi(); } diff --git a/apps/opencs/view/settings/windowpage.cpp b/apps/opencs/view/settings/windowpage.cpp index 5bf5f2161..42d72cf75 100644 --- a/apps/opencs/view/settings/windowpage.cpp +++ b/apps/opencs/view/settings/windowpage.cpp @@ -19,7 +19,7 @@ #include "../../view/settings/abstractblock.hpp" CSVSettings::WindowPage::WindowPage(QWidget *parent): - AbstractPage("Window Size", parent) + AbstractPage("Window", parent) { // Hacks to get the stylesheet look properly #ifdef Q_OS_MAC From 39a12ab9cf0dcfdfd75a6899409e38f26affef4c Mon Sep 17 00:00:00 2001 From: k1ll Date: Thu, 27 Jun 2013 19:20:14 +0200 Subject: [PATCH 201/213] CXX Flags aren't definitions --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6948a3420..f2b1fcd4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -321,15 +321,15 @@ endif() # Compiler settings if (CMAKE_COMPILER_IS_GNUCC) - add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long) + SET(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}") # Silence warnings in OGRE headers. Remove once OGRE got fixed! - add_definitions (-Wno-ignored-qualifiers) + SET(CMAKE_CXX_FLAGS "-Wno-ignored-qualifiers ${CMAKE_CXX_FLAGS}") execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6) - add_definitions (-Wno-unused-but-set-parameter) + SET(CMAKE_CXX_FLAGS "-Wno-unused-but-set-parameter ${CMAKE_CXX_FLAGS}") endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6) endif (CMAKE_COMPILER_IS_GNUCC) From 123a60581ff5bbae3b20fc749c7a97b92cbf1b8f Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Jun 2013 21:45:32 +0200 Subject: [PATCH 202/213] Only link to SDL2main on windows --- apps/openmw/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 501e5c5ae..fdd0b900a 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -112,7 +112,6 @@ target_link_libraries(openmw ${BULLET_LIBRARIES} ${MYGUI_LIBRARIES} ${SDL2_LIBRARY} - ${SDL2MAIN_LIBRARY} ${MYGUI_PLATFORM_LIBRARIES} ${SHINY_LIBRARIES} "oics" @@ -120,6 +119,10 @@ target_link_libraries(openmw components ) +if (NOT UNIX) +target_link_libraries(openmw ${SDL2MAIN_LIBRARY}) +endif() + # Fix for not visible pthreads functions for linker with glibc 2.15 if (UNIX AND NOT APPLE) target_link_libraries(openmw ${CMAKE_THREAD_LIBS_INIT}) From b095c2485418d3588b811dcd7da37f23a5fefabd Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Thu, 27 Jun 2013 14:11:20 -0700 Subject: [PATCH 203/213] resize actor collision boxes on death --- apps/openmw/mwbase/world.hpp | 2 ++ apps/openmw/mwmechanics/character.cpp | 4 ++++ apps/openmw/mwworld/worldimp.cpp | 14 ++++++++++++++ apps/openmw/mwworld/worldimp.hpp | 2 ++ 4 files changed, 22 insertions(+) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 86a6a89d2..cf41f97df 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -345,6 +345,8 @@ namespace MWBase virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector& out) = 0; ///< get all items in active cells owned by this Npc + virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0; + virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; virtual int canRest() = 0; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index abc6b82c4..d3dbb9325 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -462,6 +462,10 @@ void CharacterController::update(float duration, Movement &movement) mAnimation->disable("torch"); } } + else if (cls.getCreatureStats(mPtr).isDead()) + { + MWBase::Environment::get().getWorld()->enableActorCollision(mPtr, false); + } if(mAnimation && !mSkipAnim) { diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 16cba2ea8..662d46a4b 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1751,4 +1751,18 @@ namespace MWWorld out.push_back(searchPtrViaHandle(*it)); } } + + void World::enableActorCollision(const MWWorld::Ptr& actor, bool enable) + { + OEngine::Physic::PhysicActor *physicActor = mPhysEngine->getCharacter(actor.getRefData().getHandle()); + + if (!enable) + { + physicActor->setScale(0.15); + } + else + { + physicActor->setScale(1); + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 12438efd4..5cf3a24bf 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -394,6 +394,8 @@ namespace MWWorld virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector& out); ///< get all items in active cells owned by this Npc + virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable); + virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); virtual int canRest(); From f43b48015e487f80810e52c12f0d4f5b4f5df2bb Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Thu, 27 Jun 2013 19:42:27 -0700 Subject: [PATCH 204/213] remove actor's collisionbox on death --- apps/openmw/mwworld/worldimp.cpp | 6 +++--- libs/openengine/bullet/physic.cpp | 10 ++++++++++ libs/openengine/bullet/physic.hpp | 3 +++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 662d46a4b..0a1e0ccdc 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1756,13 +1756,13 @@ namespace MWWorld { OEngine::Physic::PhysicActor *physicActor = mPhysEngine->getCharacter(actor.getRefData().getHandle()); - if (!enable) + if (enable) { - physicActor->setScale(0.15); + physicActor->enableCollisionBody(); } else { - physicActor->setScale(1); + physicActor->disableCollisionBody(); } } } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index bbe633847..550e71b3c 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -146,6 +146,16 @@ namespace Physic return collisionMode && onGround; } + void PhysicActor::disableCollisionBody() + { + mEngine->dynamicsWorld->removeRigidBody(mBody); + } + + void PhysicActor::enableCollisionBody() + { + mEngine->dynamicsWorld->addRigidBody(mBody); + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 80c681fe5..baeb31678 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -129,6 +129,9 @@ namespace Physic bool getOnGround() const; + void disableCollisionBody(); + void enableCollisionBody(); + //HACK: in Visual Studio 2010 and presumably above, this structures alignment // must be 16, but the built in operator new & delete don't properly // perform this alignment. From cd538538b563e3ac99948032b56ba52fc4a1c586 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 28 Jun 2013 09:00:21 +0200 Subject: [PATCH 205/213] fixed weather code --- apps/openmw/mwworld/weather.cpp | 53 +++++++++++++++++---------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 10dbdae9b..467d7e7c8 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -572,35 +572,36 @@ Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const int chance = (rand() % 100) + 1; // 1..100 int sum = 0; - for (int i = 0; i < 10; ++i) + int i = 0; + for (; i < 10; ++i) { sum += probability[i]; if (chance < sum) - { - switch (i) - { - case 1: - return "cloudy"; - case 2: - return "foggy"; - case 3: - return "overcast"; - case 4: - return "rain"; - case 5: - return "thunderstorm"; - case 6: - return "ashstorm"; - case 7: - return "blight"; - case 8: - return "snow"; - case 9: - return "blizzard"; - default: // case 0 - return "clear"; - } - } + break; + } + + switch (i) + { + case 1: + return "cloudy"; + case 2: + return "foggy"; + case 3: + return "overcast"; + case 4: + return "rain"; + case 5: + return "thunderstorm"; + case 6: + return "ashstorm"; + case 7: + return "blight"; + case 8: + return "snow"; + case 9: + return "blizzard"; + default: // case 0 + return "clear"; } } From 8bdc9ff3aeaf4b81ce1fb9b976b9fb38a8f83ab2 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Mon, 1 Jul 2013 03:56:33 +0200 Subject: [PATCH 206/213] set position of the window for multiple monitors --- apps/openmw/engine.cpp | 1 + libs/openengine/ogre/renderer.cpp | 8 ++++++-- libs/openengine/ogre/renderer.hpp | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index c0b212550..2918f5d8b 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -369,6 +369,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) windowSettings.fullscreen = settings.getBool("fullscreen", "Video"); windowSettings.window_x = settings.getInt("resolution x", "Video"); windowSettings.window_y = settings.getInt("resolution y", "Video"); + windowSettings.screen = settings.getInt("screen", "Video"); windowSettings.vsync = settings.getBool("vsync", "Video"); windowSettings.icon = "openmw.png"; std::string aa = settings.getString("antialiasing", "Video"); diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 5807a9482..2ac52d31a 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -266,11 +266,15 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& params.insert(std::make_pair("FSAA", settings.fsaa)); params.insert(std::make_pair("vsync", settings.vsync ? "true" : "false")); + SDL_Rect display_bounds; + if(SDL_GetDisplayBounds(settings.screen, &display_bounds) != 0) + throw std::runtime_error("Couldn't get display bounds!"); + // Create an application window with the following settings: mSDLWindow = SDL_CreateWindow( "OpenMW", // window title - SDL_WINDOWPOS_UNDEFINED, // initial x position - SDL_WINDOWPOS_UNDEFINED, // initial y position + display_bounds.x, // initial x position + display_bounds.y, // initial y position settings.window_x, // width, in pixels settings.window_y, // height, in pixels SDL_WINDOW_SHOWN diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index a451490fb..f4b38c52d 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -56,6 +56,7 @@ namespace OEngine bool vsync; bool fullscreen; int window_x, window_y; + int screen; std::string fsaa; std::string icon; }; From 72b7e113cc99a972606022aba6dfe99d4905d509 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Mon, 1 Jul 2013 04:08:26 +0200 Subject: [PATCH 207/213] only apply in fullscreen --- libs/openengine/ogre/renderer.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 2ac52d31a..00d94a004 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -266,15 +266,23 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& params.insert(std::make_pair("FSAA", settings.fsaa)); params.insert(std::make_pair("vsync", settings.vsync ? "true" : "false")); - SDL_Rect display_bounds; - if(SDL_GetDisplayBounds(settings.screen, &display_bounds) != 0) - throw std::runtime_error("Couldn't get display bounds!"); + int pos_x = SDL_WINDOWPOS_UNDEFINED, + pos_y = SDL_WINDOWPOS_UNDEFINED; + + if(settings.fullscreen) + { + SDL_Rect display_bounds; + if(SDL_GetDisplayBounds(settings.screen, &display_bounds) != 0) + throw std::runtime_error("Couldn't get display bounds!"); + pos_x = display_bounds.x; + pos_y = display_bounds.y; + } // Create an application window with the following settings: mSDLWindow = SDL_CreateWindow( "OpenMW", // window title - display_bounds.x, // initial x position - display_bounds.y, // initial y position + pos_x, // initial x position + pos_y, // initial y position settings.window_x, // width, in pixels settings.window_y, // height, in pixels SDL_WINDOW_SHOWN From e3d8bdbafefe032aa6e14c224363da5c1abfa9c7 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Tue, 2 Jul 2013 17:29:47 +0200 Subject: [PATCH 208/213] autorepeat scrollbar --- apps/openmw/mwgui/waitdialog.cpp | 7 +- apps/openmw/mwgui/waitdialog.hpp | 3 +- apps/openmw/mwgui/widgets.cpp | 92 ++++++++++++++++++++++++++ apps/openmw/mwgui/widgets.hpp | 31 +++++++++ apps/openmw/mwgui/windowmanagerimp.cpp | 1 + files/mygui/openmw_wait_dialog.layout | 2 +- 6 files changed, 130 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index ad2b4710c..f9a03de71 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -15,8 +15,6 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" -#include "widgets.hpp" - namespace MWGui { @@ -53,15 +51,14 @@ namespace MWGui getWidget(mDateTimeText, "DateTimeText"); getWidget(mRestText, "RestText"); getWidget(mHourText, "HourText"); - getWidget(mHourSlider, "HourSlider"); getWidget(mUntilHealedButton, "UntilHealedButton"); getWidget(mWaitButton, "WaitButton"); getWidget(mCancelButton, "CancelButton"); + getWidget(mHourSlider, "HourSlider"); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onCancelButtonClicked); mUntilHealedButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onUntilHealedButtonClicked); mWaitButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onWaitButtonClicked); - mHourSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &WaitDialog::onHourSliderChangedPosition); mProgressBar.setVisible (false); @@ -231,6 +228,8 @@ namespace MWGui void WaitDialog::onFrame(float dt) { + mHourSlider->updateTime(dt); + if (!mWaiting) return; diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index d06d7d112..2723f7a80 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -2,6 +2,7 @@ #define MWGUI_WAIT_DIALOG_H #include "windowbase.hpp" +#include "widgets.hpp" namespace MWGui { @@ -38,10 +39,10 @@ namespace MWGui MyGUI::TextBox* mDateTimeText; MyGUI::TextBox* mRestText; MyGUI::TextBox* mHourText; - MyGUI::ScrollBar* mHourSlider; MyGUI::Button* mUntilHealedButton; MyGUI::Button* mWaitButton; MyGUI::Button* mCancelButton; + MWGui::Widgets::MWScrollBar* mHourSlider; bool mWaiting; bool mSleeping; diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 1662c0597..7752b6a94 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -893,5 +893,97 @@ namespace MWGui { align(); } + + MWScrollBar::MWScrollBar() + : mEnableRepeat(true) + , mRepeatTriggerTime(0.5) + , mRepeatStepTime(0.1) + , mStepDecrease(0) + , mStepIncrease(0) + { + } + + MWScrollBar::~MWScrollBar() + { + } + + void MWScrollBar::initialiseOverride() + { + Base::initialiseOverride(); + + mWidgetStart->eventMouseButtonPressed += MyGUI::newDelegate(this, &MWScrollBar::onDecreaseButtonPressed); + mWidgetStart->eventMouseButtonReleased += MyGUI::newDelegate(this, &MWScrollBar::onDecreaseButtonReleased); + mWidgetEnd->eventMouseButtonPressed += MyGUI::newDelegate(this, &MWScrollBar::onIncreaseButtonPressed); + mWidgetEnd->eventMouseButtonReleased += MyGUI::newDelegate(this, &MWScrollBar::onIncreaseButtonReleased); + } + + void MWScrollBar::setEnableRepeat(bool enable) + { + mEnableRepeat = enable; + } + + bool MWScrollBar::getEnableRepeat() + { + return mEnableRepeat; + } + + void MWScrollBar::getRepeat(float &trigger, float &step) + { + trigger = mRepeatTriggerTime; + step = mRepeatStepTime; + } + + void MWScrollBar::setRepeat(float trigger, float step) + { + mRepeatTriggerTime = trigger; + mRepeatStepTime = step; + } + + void MWScrollBar::updateTime(float dt) + { + if(!mEnableRepeat) + return; + + if(mStepDecrease > 0) + { + mStepDecrease -= dt; + if(mStepDecrease <= 0 && mScrollPosition > 0) + { + mScrollPosition -= 1; + eventScrollChangePosition(this, mScrollPosition); + mStepDecrease += mRepeatStepTime; + } + } + if(mStepIncrease > 0) + { + mStepIncrease -= dt; + if(mStepIncrease <= 0 && mScrollPosition < mScrollRange-1) + { + mScrollPosition += 1; + eventScrollChangePosition(this, mScrollPosition); + mStepIncrease += mRepeatStepTime; + } + } + } + + void MWScrollBar::onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) + { + mStepDecrease = mRepeatTriggerTime; + } + + void MWScrollBar::onDecreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) + { + mStepDecrease = 0; + } + + void MWScrollBar::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) + { + mStepIncrease = mRepeatTriggerTime; + } + + void MWScrollBar::onIncreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) + { + mStepIncrease = 0; + } } } diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 156794691..362746ae2 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace MyGUI { @@ -407,6 +408,36 @@ namespace MWGui virtual void onWidgetCreated(MyGUI::Widget* _widget); }; + + class MWScrollBar : public MyGUI::ScrollBar + { + MYGUI_RTTI_DERIVED(MWScrollBar) + + public: + MWScrollBar(); + + void setEnableRepeat(bool enable); + bool getEnableRepeat(); + void getRepeat(float &trigger, float &step); + void setRepeat(float trigger, float step); + void updateTime(float dt); + + protected: + virtual ~MWScrollBar(); + virtual void initialiseOverride(); + + bool mEnableRepeat; + float mRepeatTriggerTime; + float mRepeatStepTime; + float mStepDecrease; + float mStepIncrease; + + private: + void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onDecreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onIncreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + }; } } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 38efbbff0..06fb96c12 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -142,6 +142,7 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); BookPage::registerMyGUIComponents (); ItemView::registerComponents(); diff --git a/files/mygui/openmw_wait_dialog.layout b/files/mygui/openmw_wait_dialog.layout index 66e0ec22f..eeb7012eb 100644 --- a/files/mygui/openmw_wait_dialog.layout +++ b/files/mygui/openmw_wait_dialog.layout @@ -16,7 +16,7 @@ - + From b43f41c2bddefa18ebe012e75328163491a323ae Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Fri, 5 Jul 2013 19:17:00 +0200 Subject: [PATCH 209/213] use a mygui controller for scrollbar repeat --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/controllers.cpp | 54 ++++++++++++++++++++++++++ apps/openmw/mwgui/controllers.hpp | 46 ++++++++++++++++++++++ apps/openmw/mwgui/waitdialog.cpp | 2 - apps/openmw/mwgui/widgets.cpp | 50 ++++++++++++------------ apps/openmw/mwgui/widgets.hpp | 8 ++-- apps/openmw/mwgui/windowmanagerimp.cpp | 2 + 7 files changed, 131 insertions(+), 33 deletions(-) create mode 100644 apps/openmw/mwgui/controllers.cpp create mode 100644 apps/openmw/mwgui/controllers.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 501e5c5ae..6dbc3e28f 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -33,7 +33,7 @@ add_openmw_dir (mwgui enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview - tradeitemmodel companionitemmodel pickpocketitemmodel fontloader + tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwgui/controllers.cpp b/apps/openmw/mwgui/controllers.cpp new file mode 100644 index 000000000..2c3ef4ae0 --- /dev/null +++ b/apps/openmw/mwgui/controllers.cpp @@ -0,0 +1,54 @@ +#include "controllers.hpp" + +namespace MWGui +{ + namespace Controllers + { + + ControllerRepeatClick::ControllerRepeatClick() : + mInit(0.5), + mStep(0.1), + mEnabled(true), + mTimeLeft(0) + { + } + + ControllerRepeatClick::~ControllerRepeatClick() + { + } + + bool ControllerRepeatClick::addTime(MyGUI::Widget* _widget, float _time) + { + if(mTimeLeft == 0) + mTimeLeft = mInit; + + mTimeLeft -= _time; + if(mTimeLeft <= 0) + { + mTimeLeft = mStep; + eventRepeatClick(_widget, this); + } + return true; + } + + void ControllerRepeatClick::setRepeat(float init, float step) + { + mInit = init; + mStep = step; + } + + void ControllerRepeatClick::setEnabled(bool enable) + { + mEnabled = enable; + } + + void ControllerRepeatClick::setProperty(const std::string& _key, const std::string& _value) + { + } + + void ControllerRepeatClick::prepareItem(MyGUI::Widget* _widget) + { + } + + } +} diff --git a/apps/openmw/mwgui/controllers.hpp b/apps/openmw/mwgui/controllers.hpp new file mode 100644 index 000000000..798acde62 --- /dev/null +++ b/apps/openmw/mwgui/controllers.hpp @@ -0,0 +1,46 @@ +#ifndef MWGUI_CONTROLLERS_H +#define MWGUI_CONTROLLERS_H + +#include +#include + + +namespace MWGui +{ + namespace Controllers + { + class ControllerRepeatClick : + public MyGUI::ControllerItem + { + MYGUI_RTTI_DERIVED( ControllerRepeatClick ) + + public: + ControllerRepeatClick(); + virtual ~ControllerRepeatClick(); + + void setRepeat(float init, float step); + void setEnabled(bool enable); + virtual void setProperty(const std::string& _key, const std::string& _value); + + // Events + typedef MyGUI::delegates::CMultiDelegate2 EventHandle_RepeatClickVoid; + + /** Event : Repeat Click.\n + signature : void method(MyGUI::Widget* _sender, MyGUI::ControllerItem *_controller)\n + */ + EventHandle_RepeatClickVoid eventRepeatClick; + + private: + bool addTime(MyGUI::Widget* _widget, float _time); + void prepareItem(MyGUI::Widget* _widget); + + private: + float mInit; + float mStep; + bool mEnabled; + float mTimeLeft; + }; + } +} + +#endif diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index f9a03de71..97c869b07 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -228,8 +228,6 @@ namespace MWGui void WaitDialog::onFrame(float dt) { - mHourSlider->updateTime(dt); - if (!mWaiting) return; diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 7752b6a94..d147b28b1 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -898,8 +899,6 @@ namespace MWGui : mEnableRepeat(true) , mRepeatTriggerTime(0.5) , mRepeatStepTime(0.1) - , mStepDecrease(0) - , mStepIncrease(0) { } @@ -939,51 +938,50 @@ namespace MWGui mRepeatStepTime = step; } - void MWScrollBar::updateTime(float dt) + void MWScrollBar::repeatClick(MyGUI::Widget* _widget, MyGUI::ControllerItem* _controller) { - if(!mEnableRepeat) - return; - - if(mStepDecrease > 0) + if(mIsIncreasing && mScrollPosition < mScrollRange-1) { - mStepDecrease -= dt; - if(mStepDecrease <= 0 && mScrollPosition > 0) - { - mScrollPosition -= 1; - eventScrollChangePosition(this, mScrollPosition); - mStepDecrease += mRepeatStepTime; - } + mScrollPosition += 1; + eventScrollChangePosition(this, mScrollPosition); } - if(mStepIncrease > 0) + else if(!mIsIncreasing && mScrollPosition > 0) { - mStepIncrease -= dt; - if(mStepIncrease <= 0 && mScrollPosition < mScrollRange-1) - { - mScrollPosition += 1; - eventScrollChangePosition(this, mScrollPosition); - mStepIncrease += mRepeatStepTime; - } + mScrollPosition -= 1; + eventScrollChangePosition(this, mScrollPosition); } } void MWScrollBar::onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { - mStepDecrease = mRepeatTriggerTime; + mIsIncreasing = false; + MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(MWGui::Controllers::ControllerRepeatClick::getClassTypeName()); + MWGui::Controllers::ControllerRepeatClick* controller = item->castType(); + controller->eventRepeatClick += newDelegate(this, &MWScrollBar::repeatClick); + controller->setEnabled(mEnableRepeat); + controller->setRepeat(mRepeatTriggerTime, mRepeatStepTime); + MyGUI::ControllerManager::getInstance().addItem(this, controller); } void MWScrollBar::onDecreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { - mStepDecrease = 0; + MyGUI::ControllerManager::getInstance().removeItem(this); } void MWScrollBar::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { - mStepIncrease = mRepeatTriggerTime; + mIsIncreasing = true; + MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(MWGui::Controllers::ControllerRepeatClick::getClassTypeName()); + MWGui::Controllers::ControllerRepeatClick* controller = item->castType(); + controller->eventRepeatClick += newDelegate(this, &MWScrollBar::repeatClick); + controller->setEnabled(mEnableRepeat); + controller->setRepeat(mRepeatTriggerTime, mRepeatStepTime); + MyGUI::ControllerManager::getInstance().addItem(this, controller); } void MWScrollBar::onIncreaseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { - mStepIncrease = 0; + MyGUI::ControllerManager::getInstance().removeItem(this); } } } diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 362746ae2..1630ab3c9 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -3,6 +3,7 @@ #include "../mwworld/esmstore.hpp" #include "../mwmechanics/stat.hpp" +#include "controllers.hpp" #include #include @@ -415,22 +416,21 @@ namespace MWGui public: MWScrollBar(); + virtual ~MWScrollBar(); void setEnableRepeat(bool enable); bool getEnableRepeat(); void getRepeat(float &trigger, float &step); void setRepeat(float trigger, float step); - void updateTime(float dt); protected: - virtual ~MWScrollBar(); virtual void initialiseOverride(); + void repeatClick(MyGUI::Widget* _widget, MyGUI::ControllerItem* _controller); bool mEnableRepeat; float mRepeatTriggerTime; float mRepeatStepTime; - float mStepDecrease; - float mStepIncrease; + bool mIsIncreasing; private: void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 06fb96c12..f20f03611 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -146,6 +146,8 @@ namespace MWGui BookPage::registerMyGUIComponents (); ItemView::registerComponents(); + MyGUI::FactoryManager::getInstance().registerFactory("Controller"); + MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); MyGUI::ResourceManager::getInstance().load("core.xml"); From 26bd2a5301d5b75e70c7c21f0abff4546bd5899c Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Fri, 5 Jul 2013 20:28:46 +0200 Subject: [PATCH 210/213] use the new scrollbar; range dependent step size; fix --- apps/openmw/mwgui/widgets.cpp | 46 +++++++++++++++++++---- apps/openmw/mwgui/widgets.hpp | 3 ++ files/mygui/openmw_chargen_race.layout | 2 +- files/mygui/openmw_count_window.layout | 2 +- files/mygui/openmw_dialogue_window.layout | 2 +- files/mygui/openmw_edit.skin.xml | 2 +- files/mygui/openmw_edit_effect.layout | 8 ++-- files/mygui/openmw_list.skin.xml | 4 +- files/mygui/openmw_map_window_skin.xml | 4 +- files/mygui/openmw_scroll_skin.xml | 4 +- files/mygui/openmw_settings_window.layout | 22 +++++------ 11 files changed, 67 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index d147b28b1..c57630f08 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -899,6 +899,7 @@ namespace MWGui : mEnableRepeat(true) , mRepeatTriggerTime(0.5) , mRepeatStepTime(0.1) + , mStepSize(0) { } @@ -908,12 +909,18 @@ namespace MWGui void MWScrollBar::initialiseOverride() { - Base::initialiseOverride(); + ScrollBar::initialiseOverride(); - mWidgetStart->eventMouseButtonPressed += MyGUI::newDelegate(this, &MWScrollBar::onDecreaseButtonPressed); - mWidgetStart->eventMouseButtonReleased += MyGUI::newDelegate(this, &MWScrollBar::onDecreaseButtonReleased); - mWidgetEnd->eventMouseButtonPressed += MyGUI::newDelegate(this, &MWScrollBar::onIncreaseButtonPressed); - mWidgetEnd->eventMouseButtonReleased += MyGUI::newDelegate(this, &MWScrollBar::onIncreaseButtonReleased); + if(mWidgetStart) + { + mWidgetStart->eventMouseButtonPressed += MyGUI::newDelegate(this, &MWScrollBar::onDecreaseButtonPressed); + mWidgetStart->eventMouseButtonReleased += MyGUI::newDelegate(this, &MWScrollBar::onDecreaseButtonReleased); + } + if(mWidgetEnd) + { + mWidgetEnd->eventMouseButtonPressed += MyGUI::newDelegate(this, &MWScrollBar::onIncreaseButtonPressed); + mWidgetEnd->eventMouseButtonReleased += MyGUI::newDelegate(this, &MWScrollBar::onIncreaseButtonReleased); + } } void MWScrollBar::setEnableRepeat(bool enable) @@ -938,17 +945,42 @@ namespace MWGui mRepeatStepTime = step; } + void MWScrollBar::setStepSize(int step) + { + mStepSize = step; + } + + int MWScrollBar::getStepSize() + { + return mStepSize; + } + void MWScrollBar::repeatClick(MyGUI::Widget* _widget, MyGUI::ControllerItem* _controller) { + int stepSize = mStepSize; + if(stepSize == 0) + stepSize = mScrollRange/20; + if(mIsIncreasing && mScrollPosition < mScrollRange-1) { - mScrollPosition += 1; + if(mScrollPosition + stepSize > mScrollRange-1) + mScrollPosition = mScrollRange-1; + else + mScrollPosition += stepSize; + eventScrollChangePosition(this, mScrollPosition); + updateTrack(); } else if(!mIsIncreasing && mScrollPosition > 0) { - mScrollPosition -= 1; + int newPos = mScrollPosition - stepSize; + if(newPos < 0) + mScrollPosition = 0; + else + mScrollPosition -= stepSize; + eventScrollChangePosition(this, mScrollPosition); + updateTrack(); } } diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 1630ab3c9..136056bf4 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -422,6 +422,8 @@ namespace MWGui bool getEnableRepeat(); void getRepeat(float &trigger, float &step); void setRepeat(float trigger, float step); + void setStepSize(int step); + int getStepSize(); protected: virtual void initialiseOverride(); @@ -431,6 +433,7 @@ namespace MWGui float mRepeatTriggerTime; float mRepeatStepTime; bool mIsIncreasing; + int mStepSize; private: void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); diff --git a/files/mygui/openmw_chargen_race.layout b/files/mygui/openmw_chargen_race.layout index c569abb86..55dbe3218 100644 --- a/files/mygui/openmw_chargen_race.layout +++ b/files/mygui/openmw_chargen_race.layout @@ -14,7 +14,7 @@ - + diff --git a/files/mygui/openmw_count_window.layout b/files/mygui/openmw_count_window.layout index 5812ec7fd..4e24277af 100644 --- a/files/mygui/openmw_count_window.layout +++ b/files/mygui/openmw_count_window.layout @@ -16,7 +16,7 @@ - + diff --git a/files/mygui/openmw_dialogue_window.layout b/files/mygui/openmw_dialogue_window.layout index 46090d000..a314ba312 100644 --- a/files/mygui/openmw_dialogue_window.layout +++ b/files/mygui/openmw_dialogue_window.layout @@ -10,7 +10,7 @@ - + diff --git a/files/mygui/openmw_edit.skin.xml b/files/mygui/openmw_edit.skin.xml index da21385e2..1f14f6f66 100644 --- a/files/mygui/openmw_edit.skin.xml +++ b/files/mygui/openmw_edit.skin.xml @@ -45,7 +45,7 @@ - + diff --git a/files/mygui/openmw_edit_effect.layout b/files/mygui/openmw_edit_effect.layout index cad22c064..fa1e58b9d 100644 --- a/files/mygui/openmw_edit_effect.layout +++ b/files/mygui/openmw_edit_effect.layout @@ -31,7 +31,7 @@ - + @@ -39,7 +39,7 @@ - + @@ -56,7 +56,7 @@ - + @@ -72,7 +72,7 @@ - + diff --git a/files/mygui/openmw_list.skin.xml b/files/mygui/openmw_list.skin.xml index a5065c7ca..d680f80d2 100644 --- a/files/mygui/openmw_list.skin.xml +++ b/files/mygui/openmw_list.skin.xml @@ -120,7 +120,7 @@ - + @@ -150,7 +150,7 @@ - + diff --git a/files/mygui/openmw_map_window_skin.xml b/files/mygui/openmw_map_window_skin.xml index 13f18c6d3..2f5bb4faf 100644 --- a/files/mygui/openmw_map_window_skin.xml +++ b/files/mygui/openmw_map_window_skin.xml @@ -5,7 +5,7 @@ - - + + diff --git a/files/mygui/openmw_scroll_skin.xml b/files/mygui/openmw_scroll_skin.xml index 1b94f0c29..76e22c69f 100644 --- a/files/mygui/openmw_scroll_skin.xml +++ b/files/mygui/openmw_scroll_skin.xml @@ -4,12 +4,12 @@ - + - + diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 3c65bb690..b4ac8a247 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -15,7 +15,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -64,35 +64,35 @@ - + - + - + - + - + @@ -117,7 +117,7 @@ - + @@ -182,7 +182,7 @@ - + @@ -207,7 +207,7 @@ - + @@ -215,7 +215,7 @@ - + From 76d95dffb658e3fe93d53df31c92e9f0b199971e Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 5 Jul 2013 23:52:46 +0400 Subject: [PATCH 211/213] special case for loading StartScript records --- apps/openmw/mwworld/store.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index b49569f24..4ccd0e689 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -273,6 +273,14 @@ namespace MWWorld mStatic[scpt.mId] = scpt; } + template <> + inline void Store::load(ESM::ESMReader &esm, const std::string &id) { + ESM::StartScript s; + s.load(esm); + s.mId = Misc::StringUtils::toLower(s.mScript); + mStatic[s.mId] = s; + } + template <> class Store : public StoreBase { From 58fce74620e44cc5ceec5adb9f1ff6a94f4fe02b Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 6 Jul 2013 16:40:57 +0200 Subject: [PATCH 212/213] Use the already existing mScrollPage as step size for scrollbar button repeats; increased precision of options menu sliders --- apps/openmw/mwgui/controllers.cpp | 4 +-- apps/openmw/mwgui/widgets.cpp | 15 +---------- apps/openmw/mwgui/widgets.hpp | 3 --- files/mygui/openmw_settings_window.layout | 33 +++++++++++++++-------- 4 files changed, 25 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwgui/controllers.cpp b/apps/openmw/mwgui/controllers.cpp index 2c3ef4ae0..e62fb3fce 100644 --- a/apps/openmw/mwgui/controllers.cpp +++ b/apps/openmw/mwgui/controllers.cpp @@ -23,9 +23,9 @@ namespace MWGui mTimeLeft = mInit; mTimeLeft -= _time; - if(mTimeLeft <= 0) + while (mTimeLeft <= 0) { - mTimeLeft = mStep; + mTimeLeft += mStep; eventRepeatClick(_widget, this); } return true; diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index c57630f08..04ef0e7cb 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -899,7 +899,6 @@ namespace MWGui : mEnableRepeat(true) , mRepeatTriggerTime(0.5) , mRepeatStepTime(0.1) - , mStepSize(0) { } @@ -945,21 +944,9 @@ namespace MWGui mRepeatStepTime = step; } - void MWScrollBar::setStepSize(int step) - { - mStepSize = step; - } - - int MWScrollBar::getStepSize() - { - return mStepSize; - } - void MWScrollBar::repeatClick(MyGUI::Widget* _widget, MyGUI::ControllerItem* _controller) { - int stepSize = mStepSize; - if(stepSize == 0) - stepSize = mScrollRange/20; + int stepSize = mScrollPage; if(mIsIncreasing && mScrollPosition < mScrollRange-1) { diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 136056bf4..1630ab3c9 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -422,8 +422,6 @@ namespace MWGui bool getEnableRepeat(); void getRepeat(float &trigger, float &step); void setRepeat(float trigger, float step); - void setStepSize(int step); - int getStepSize(); protected: virtual void initialiseOverride(); @@ -433,7 +431,6 @@ namespace MWGui float mRepeatTriggerTime; float mRepeatStepTime; bool mIsIncreasing; - int mStepSize; private: void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index b4ac8a247..ab91aed78 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -16,7 +16,8 @@ - + + @@ -31,7 +32,8 @@ - + + @@ -65,35 +67,40 @@ - + + - + + - + + - + + - + + @@ -118,7 +125,8 @@ - + + @@ -183,7 +191,8 @@ - + + @@ -208,7 +217,8 @@ - + + @@ -216,7 +226,8 @@ - + + From 72600a16cffc242107a6492bc35a2f0ed30418dc Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 6 Jul 2013 17:02:40 +0200 Subject: [PATCH 213/213] Fix chargen race menu bug, updating a render target from within MyGUI's ControllerManager update is not a good idea --- apps/openmw/mwgui/charactercreation.cpp | 6 ++++++ apps/openmw/mwgui/charactercreation.hpp | 1 + apps/openmw/mwgui/race.cpp | 14 ++++++++++++++ apps/openmw/mwgui/race.hpp | 4 ++++ apps/openmw/mwgui/windowmanagerimp.cpp | 1 + apps/openmw/mwrender/characterpreview.cpp | 3 +++ apps/openmw/mwrender/characterpreview.hpp | 1 + 7 files changed, 30 insertions(+) diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index fc8c24484..6a6c596be 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -238,6 +238,12 @@ namespace MWGui } } + void CharacterCreation::doRenderUpdate() + { + if (mRaceDialog) + mRaceDialog->doRenderUpdate(); + } + void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat& value) { mPlayerHealth = value; diff --git a/apps/openmw/mwgui/charactercreation.hpp b/apps/openmw/mwgui/charactercreation.hpp index 586faf966..bd8826677 100644 --- a/apps/openmw/mwgui/charactercreation.hpp +++ b/apps/openmw/mwgui/charactercreation.hpp @@ -41,6 +41,7 @@ namespace MWGui void setValue (const std::string& id, const MWMechanics::DynamicStat& value); void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat& value); void configureSkills (const SkillList& major, const SkillList& minor); + void doRenderUpdate(); private: //Dialogs diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 9065333f5..ba06c8d10 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -32,6 +32,7 @@ namespace MWGui , mFaceIndex(0) , mHairIndex(0) , mCurrentAngle(0) + , mPreviewDirty(true) { // Centre dialog center(); @@ -126,6 +127,8 @@ namespace MWGui mHairIndex = boost::lexical_cast(index) - 1; mPreviewImage->setImageTexture ("CharacterHeadPreview"); + + mPreviewDirty = true; } @@ -174,6 +177,7 @@ namespace MWGui float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2; float diff = angle - mCurrentAngle; mPreview->update (diff); + mPreviewDirty = true; mCurrentAngle += diff; } @@ -286,6 +290,16 @@ namespace MWGui record.mHair = mAvailableHairs[mHairIndex]; mPreview->setPrototype(record); + mPreviewDirty = true; + } + + void RaceDialog::doRenderUpdate() + { + if (mPreviewDirty) + { + mPreview->render(); + mPreviewDirty = false; + } } void RaceDialog::updateRaces() diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index 1d48c67cd..914ae8096 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -52,6 +52,8 @@ namespace MWGui */ EventHandle_Void eventBack; + void doRenderUpdate(); + protected: void onHeadRotate(MyGUI::ScrollBar* _sender, size_t _position); @@ -98,6 +100,8 @@ namespace MWGui float mCurrentAngle; MWRender::RaceSelectionPreview* mPreview; + + bool mPreviewDirty; }; } #endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index f20f03611..0d40bc2be 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1292,6 +1292,7 @@ namespace MWGui void WindowManager::frameStarted (float dt) { mInventoryWindow->doRenderUpdate (); + mCharGen->doRenderUpdate(); } void WindowManager::updatePlayer() diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index e4bba289f..e9ecedc55 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -230,7 +230,10 @@ namespace MWRender mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL); updateCamera(); + } + void RaceSelectionPreview::render() + { mRenderTarget->update(); } diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index 562cb3784..b2dfc9679 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -93,6 +93,7 @@ namespace MWRender RaceSelectionPreview(); virtual void onSetup(); + void render(); void update(float angle);