diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 3647f8ccb0..bda903d561 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -357,7 +357,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) // Create input and UI first to set up a bootstrapping environment for // showing a loading screen and keeping the window responsive while doing so - std::string keybinderUser = (mCfgMgr.getUserConfigPath() / "input.xml").string(); + std::string keybinderUser = (mCfgMgr.getUserConfigPath() / "input_v1.xml").string(); bool keybinderUserExists = boost::filesystem::exists(keybinderUser); MWInput::InputManager* input = new MWInput::InputManager (*mOgre, *this, keybinderUser, keybinderUserExists, mGrab); mEnvironment.setInputManager (input); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 338eb2a7c9..503ccaf250 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -10,6 +10,7 @@ #include #include +#include #if defined(_WIN32) // For OutputDebugString @@ -309,7 +310,8 @@ int main(int argc, char**argv) std::cerr.rdbuf (&sb); #else // Redirect cout and cerr to openmw.log - std::ofstream logfile (std::string(cfgMgr.getLogPath().string() + "/openmw.log").c_str()); + boost::filesystem::ofstream logfile (boost::filesystem::path( + cfgMgr.getLogPath() / "/openmw.log")); boost::iostreams::stream_buffer coutsb; std::ostream oldcout(cout_rdbuf); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 4a3093b10d..3f85059ce1 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -179,6 +179,7 @@ namespace MWSound if(!mOutput->isInitialized()) return; std::cout <<"Playing "<begin(), resourcesInThisGroup->end()); + Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups (); + for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it) + { + Ogre::StringVectorPtr resourcesInThisGroup = mResourceMgr.findResourceNames(*it, + "Music/"+mCurrentPlaylist+"/*"); + filelist.insert(filelist.end(), resourcesInThisGroup->begin(), resourcesInThisGroup->end()); + } + mMusicFiles[mCurrentPlaylist] = filelist; } + else + filelist = mMusicFiles[mCurrentPlaylist]; if(!filelist.size()) return; int i = rand()%filelist.size(); + + // Don't play the same music track twice in a row + if (filelist[i] == mLastPlayedMusic) + { + if (i-1 == int(filelist.size())) + i = 0; + else + ++i; + } + streamMusicFull(filelist[i]); } diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index ab9dcf7345..558b6966af 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -31,6 +31,10 @@ namespace MWSound std::auto_ptr mOutput; + // Caches available music tracks by + std::map mMusicFiles; + std::string mLastPlayedMusic; // The music file that was last played + float mMasterVolume; float mSFXVolume; float mMusicVolume; diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 1156cbc152..fdeb290e5f 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -3,22 +3,8 @@ namespace MWWorld { - -void Store::load(ESM::ESMReader &esm, const std::string &id) +void Store::handleMovedCellRefs(ESM::ESMReader& esm, ESM::Cell* cell) { - // Don't automatically assume that a new cell must be spawned. Multiple plugins write to the same cell, - // and we merge all this data into one Cell object. However, we can't simply search for the cell id, - // as many exterior cells do not have a name. Instead, we need to search by (x,y) coordinates - and they - // are not available until both cells have been loaded! So first, proceed as usual. - - // All cells have a name record, even nameless exterior cells. - std::string idLower = Misc::StringUtils::lowerCase(id); - ESM::Cell *cell = new ESM::Cell; - cell->mName = id; - - //First part of cell loading - cell->preLoad(esm); - //Handling MovedCellRefs, there is no way to do it inside loadcell while (esm.isNextSub("MVRF")) { ESM::CellRef ref; @@ -43,35 +29,58 @@ void Store::load(ESM::ESMReader &esm, const std::string &id) else *iter = ref; } +} + +void Store::load(ESM::ESMReader &esm, const std::string &id) +{ + // Don't automatically assume that a new cell must be spawned. Multiple plugins write to the same cell, + // and we merge all this data into one Cell object. However, we can't simply search for the cell id, + // as many exterior cells do not have a name. Instead, we need to search by (x,y) coordinates - and they + // are not available until both cells have been loaded at least partially! + + // All cells have a name record, even nameless exterior cells. + std::string idLower = Misc::StringUtils::lowerCase(id); + ESM::Cell cell; + cell.mName = id; - //Second part of cell loading - cell->postLoad(esm); + // Load the (x,y) coordinates of the cell, if it is an exterior cell, + // so we can find the cell we need to merge with + cell.loadData(esm); - if(cell->mData.mFlags & ESM::Cell::Interior) + if(cell.mData.mFlags & ESM::Cell::Interior) { // Store interior cell by name, try to merge with existing parent data. ESM::Cell *oldcell = const_cast(search(idLower)); if (oldcell) { - // push the new references on the list of references to manage - oldcell->mContextList.push_back(cell->mContextList.at(0)); - // copy list into new cell - cell->mContextList = oldcell->mContextList; - // have new cell replace old cell - ESM::Cell::merge(oldcell, cell); + // merge new cell into old cell + // push the new references on the list of references to manage (saveContext = true) + oldcell->mData = cell.mData; + oldcell->loadCell(esm, true); } else - mInt[idLower] = *cell; + { + // spawn a new cell + cell.loadCell(esm, true); + + mInt[idLower] = cell; + } } else { // Store exterior cells by grid position, try to merge with existing parent data. - ESM::Cell *oldcell = const_cast(search(cell->getGridX(), cell->getGridY())); + ESM::Cell *oldcell = const_cast(search(cell.getGridX(), cell.getGridY())); if (oldcell) { + // merge new cell into old cell + oldcell->mData = cell.mData; + oldcell->loadCell(esm, false); + + // handle moved ref (MVRF) subrecords + handleMovedCellRefs (esm, &cell); + // push the new references on the list of references to manage - oldcell->mContextList.push_back(cell->mContextList.at(0)); - // copy list into new cell - cell->mContextList = oldcell->mContextList; + oldcell->postLoad(esm); + // merge lists of leased references, use newer data in case of conflict - for (ESM::MovedCellRefTracker::const_iterator it = cell->mMovedRefs.begin(); it != cell->mMovedRefs.end(); ++it) { + for (ESM::MovedCellRefTracker::const_iterator it = cell.mMovedRefs.begin(); it != cell.mMovedRefs.end(); ++it) { // remove reference from current leased ref tracker and add it to new cell ESM::MovedCellRefTracker::iterator itold = std::find(oldcell->mMovedRefs.begin(), oldcell->mMovedRefs.end(), it->mRefNum); if (itold != oldcell->mMovedRefs.end()) { @@ -82,13 +91,24 @@ void Store::load(ESM::ESMReader &esm, const std::string &id) *itold = *it; } } - cell->mMovedRefs = oldcell->mMovedRefs; - // have new cell replace old cell - ESM::Cell::merge(oldcell, cell); + + // We don't need to merge mLeasedRefs of cell / oldcell. This list is filled when another cell moves a + // reference to this cell, so the list for the new cell should be empty. The list for oldcell, + // however, could have leased refs in it and so should be kept. } else - mExt[std::make_pair(cell->mData.mX, cell->mData.mY)] = *cell; + { + // spawn a new cell + cell.loadCell(esm, false); + + // handle moved ref (MVRF) subrecords + handleMovedCellRefs (esm, &cell); + + // push the new references on the list of references to manage + cell.postLoad(esm); + + mExt[std::make_pair(cell.mData.mX, cell.mData.mY)] = cell; + } } - delete cell; } } diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 1dfb2f9766..a04267f499 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -591,6 +591,8 @@ namespace MWWorld return search(cell.mName); } + void handleMovedCellRefs(ESM::ESMReader& esm, ESM::Cell* cell); + public: ESMStore *mEsmStore; diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index 0830c5de69..83864569fb 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -50,18 +50,14 @@ namespace ESM return ref.mRefNum == refNum; } - void Cell::load(ESMReader &esm, bool saveContext) { - // Ignore this for now, it might mean we should delete the entire - // cell? - // TODO: treat the special case "another plugin moved this ref, but we want to delete it"! - if (esm.isNextSub("DELE")) { - esm.skipHSub(); - } - - esm.getHNT(mData, "DATA", 12); + loadData(esm); + loadCell(esm, saveContext); +} +void Cell::loadCell(ESMReader &esm, bool saveContext) +{ mNAM0 = 0; if (mData.mFlags & Interior) @@ -73,12 +69,10 @@ void Cell::load(ESMReader &esm, bool saveContext) esm.getHT(waterl); mWater = (float) waterl; mWaterInt = true; - mHasWaterLevelRecord = true; } else if (esm.isNextSub("WHGT")) { esm.getHT(mWater); - mHasWaterLevelRecord = true; } // Quasi-exterior cells have a region (which determines the @@ -107,6 +101,18 @@ void Cell::load(ESMReader &esm, bool saveContext) } } +void Cell::loadData(ESMReader &esm) +{ + // Ignore this for now, it might mean we should delete the entire + // cell? + // TODO: treat the special case "another plugin moved this ref, but we want to delete it"! + if (esm.isNextSub("DELE")) { + esm.skipHSub(); + } + + esm.getHNT(mData, "DATA", 12); +} + void Cell::preLoad(ESMReader &esm) //Can't be "load" because it conflicts with function in esmtool { this->load(esm, false); @@ -124,14 +130,12 @@ void Cell::save(ESMWriter &esm) const esm.writeHNT("DATA", mData, 12); if (mData.mFlags & Interior) { - if (mHasWaterLevelRecord) { - if (mWaterInt) { - int water = - (mWater >= 0) ? (int) (mWater + 0.5) : (int) (mWater - 0.5); - esm.writeHNT("INTV", water); - } else { - esm.writeHNT("WHGT", mWater); - } + if (mWaterInt) { + int water = + (mWater >= 0) ? (int) (mWater + 0.5) : (int) (mWater - 0.5); + esm.writeHNT("INTV", water); + } else { + esm.writeHNT("WHGT", mWater); } if (mData.mFlags & QuasiEx) @@ -228,19 +232,6 @@ bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref) mAmbi.mFogDensity = 0; } - void Cell::merge(Cell *original, Cell *modified) - { - float waterLevel = original->mWater; - if (modified->mHasWaterLevelRecord) - { - waterLevel = modified->mWater; - } - // else: keep original water level, instead of resetting to 0 - - *original = *modified; - original->mWater = waterLevel; - } - CellId Cell::getCellId() const { CellId id; diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index 28204c9ee1..fb4b6b28ac 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -78,10 +78,7 @@ struct Cell float mFogDensity; }; - Cell() : mWater(0), mHasWaterLevelRecord(false) {} - - /// Merge \a modified into \a original - static void merge (Cell* original, Cell* modified); + Cell() : mWater(0) {} // Interior cells are indexed by this (it's the 'id'), for exterior // cells it is optional. @@ -93,8 +90,8 @@ struct Cell std::vector mContextList; // File position; multiple positions for multiple plugin support DATAstruct mData; AMBIstruct mAmbi; + float mWater; // Water level - bool mHasWaterLevelRecord; bool mWaterInt; int mMapColor; int mNAM0; @@ -109,7 +106,10 @@ struct Cell // This method is left in for compatibility with esmtool. Parsing moved references currently requires // passing ESMStore, bit it does not know about this parameter, so we do it this way. - void load(ESMReader &esm, bool saveContext = true); + void load(ESMReader &esm, bool saveContext = true); // Load everything (except references) + void loadData(ESMReader &esm); // Load DATAstruct only + void loadCell(ESMReader &esm, bool saveContext = true); // Load everything, except DATAstruct and references + void save(ESMWriter &esm) const; bool isExterior() const diff --git a/components/nif/niffile.hpp b/components/nif/niffile.hpp index daec80ea1c..fbb64e4f74 100644 --- a/components/nif/niffile.hpp +++ b/components/nif/niffile.hpp @@ -177,42 +177,49 @@ struct KeyListT { KeyT key; NIFStream &nifReference = *nif; - for(size_t i = 0;i < count;i++) + + if(mInterpolationType == sLinearInterpolation) { - if(mInterpolationType == sLinearInterpolation) + for(size_t i = 0;i < count;i++) { readTimeAndValue(nifReference, key); mKeys.push_back(key); } - else if(mInterpolationType == sQuadraticInterpolation) + } + else if(mInterpolationType == sQuadraticInterpolation) + { + for(size_t i = 0;i < count;i++) { readQuadratic(nifReference, key); mKeys.push_back(key); } - else if(mInterpolationType == sTBCInterpolation) + } + else if(mInterpolationType == sTBCInterpolation) + { + for(size_t i = 0;i < count;i++) { readTBC(nifReference, key); mKeys.push_back(key); } - //XYZ keys aren't actually read here. - //data.hpp sees that the last type read was sXYZInterpolation and: - // Eats a floating point number, then - // Re-runs the read function 3 more times, with force enabled so that the previous values aren't cleared. - // When it does that it's reading in a bunch of sLinearInterpolation keys, not sXYZInterpolation. - else if(mInterpolationType == sXYZInterpolation) - { - //Don't try to read XYZ keys into the wrong part - if ( count != 1 ) - nif->file->fail("XYZ_ROTATION_KEY count should always be '1' . Retrieved Value: "+Ogre::StringConverter::toString(count)); - } - else if (0 == mInterpolationType) - { - if (count != 0) - nif->file->fail("Interpolation type 0 doesn't work with keys"); - } - else - nif->file->fail("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType)); } + //XYZ keys aren't actually read here. + //data.hpp sees that the last type read was sXYZInterpolation and: + // Eats a floating point number, then + // Re-runs the read function 3 more times, with force enabled so that the previous values aren't cleared. + // When it does that it's reading in a bunch of sLinearInterpolation keys, not sXYZInterpolation. + else if(mInterpolationType == sXYZInterpolation) + { + //Don't try to read XYZ keys into the wrong part + if ( count != 1 ) + nif->file->fail("XYZ_ROTATION_KEY count should always be '1' . Retrieved Value: "+Ogre::StringConverter::toString(count)); + } + else if (0 == mInterpolationType) + { + if (count != 0) + nif->file->fail("Interpolation type 0 doesn't work with keys"); + } + else + nif->file->fail("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType)); } private: diff --git a/extern/oics/ICSInputControlSystem.cpp b/extern/oics/ICSInputControlSystem.cpp index a053bbab4e..34d16ed2bd 100644 --- a/extern/oics/ICSInputControlSystem.cpp +++ b/extern/oics/ICSInputControlSystem.cpp @@ -41,8 +41,6 @@ namespace ICS this->mActive = active; - this->fillSDLKeysMap(); - ICS_LOG("Channel count = " + ToString(channelCount) ); for(size_t i=0;i( getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)).c_str() ); keyBinder.SetAttribute( "direction", "INCREASE" ); control.InsertEndChild(keyBinder); @@ -443,7 +438,7 @@ namespace ICS { TiXmlElement keyBinder( "KeyBinder" ); - keyBinder.SetAttribute( "key", keyCodeToString( + keyBinder.SetAttribute( "key", ToString( getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)).c_str() ); keyBinder.SetAttribute( "direction", "DECREASE" ); control.InsertEndChild(keyBinder); @@ -806,128 +801,14 @@ namespace ICS mDetectingBindingControl = NULL; } - void InputControlSystem::fillSDLKeysMap() - { - 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["PRNTSCRN"] = SDLK_PRINTSCREEN; - 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(SDL_Keycode key) { - return mKeyCodes[key]; + return std::string(SDL_GetKeyName(key)); } SDL_Keycode InputControlSystem::stringToKeyCode(std::string key) { - return mKeys[key]; + return SDL_GetKeyFromName(key.c_str()); } void InputControlSystem::adjustMouseRegion(Uint16 width, Uint16 height) diff --git a/extern/oics/ICSInputControlSystem.h b/extern/oics/ICSInputControlSystem.h index 4aaecdea9f..1e9c78e602 100644 --- a/extern/oics/ICSInputControlSystem.h +++ b/extern/oics/ICSInputControlSystem.h @@ -208,8 +208,6 @@ namespace ICS std::vector mChannels; ControlsKeyBinderMapType mControlsKeyBinderMap; - std::map mKeys; - std::map mKeyCodes; bool mActive; InputControlSystemLog* mLog; @@ -227,8 +225,6 @@ namespace ICS private: - void fillSDLKeysMap(); - Uint16 mClientWidth; Uint16 mClientHeight; }; diff --git a/extern/oics/ICSInputControlSystem_keyboard.cpp b/extern/oics/ICSInputControlSystem_keyboard.cpp index 0a9a34d63c..8e7415b5b1 100644 --- a/extern/oics/ICSInputControlSystem_keyboard.cpp +++ b/extern/oics/ICSInputControlSystem_keyboard.cpp @@ -43,7 +43,7 @@ namespace ICS dir = Control::DECREASE; } - addKeyBinding(mControls.back(), mKeys[xmlKeyBinder->Attribute("key")], dir); + addKeyBinding(mControls.back(), FromString(xmlKeyBinder->Attribute("key")), dir); xmlKeyBinder = xmlKeyBinder->NextSiblingElement("KeyBinder"); }