diff --git a/indra/aistatemachine/CMakeLists.txt b/indra/aistatemachine/CMakeLists.txt index 6db29a007..806261201 100644 --- a/indra/aistatemachine/CMakeLists.txt +++ b/indra/aistatemachine/CMakeLists.txt @@ -21,6 +21,7 @@ set(aistatemachine_SOURCE_FILES aistatemachine.cpp aistatemachinethread.cpp aitimer.cpp + aicondition.cpp ) set(aistatemachine_HEADER_FILES @@ -29,6 +30,7 @@ set(aistatemachine_HEADER_FILES aistatemachine.h aistatemachinethread.h aitimer.h + aicondition.h ) set_source_files_properties(${aistatemachine_HEADER_FILES} diff --git a/indra/aistatemachine/aicondition.cpp b/indra/aistatemachine/aicondition.cpp new file mode 100644 index 000000000..2c9a4f8e8 --- /dev/null +++ b/indra/aistatemachine/aicondition.cpp @@ -0,0 +1,89 @@ +/** + * @file aicondition.cpp + * @brief Implementation of AICondition + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 14/10/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#include "sys.h" +#include "aicondition.h" +#include "aistatemachine.h" + +void AIConditionBase::wait(AIStateMachine* state_machine) +{ + // The condition must be locked before calling AIStateMachine::wait(). + llassert(mutex().isSelfLocked()); + // Add the new state machine at the end. + mWaitingStateMachines.push_back(state_machine); +} + +void AIConditionBase::remove(AIStateMachine* state_machine) +{ + mutex().lock(); + // Remove all occurances of state_machine from the queue. + queue_t::iterator const end = mWaitingStateMachines.end(); + queue_t::iterator last = end; + for (queue_t::iterator iter = mWaitingStateMachines.begin(); iter != last; ++iter) + { + if (iter->get() == state_machine) + { + if (--last == iter) + { + break; + } + queue_t::value_type::swap(*iter, *last); + } + } + // This invalidates all iterators involved, including end, but not any iterators to the remaining elements. + mWaitingStateMachines.erase(last, end); + mutex().unlock(); +} + +void AIConditionBase::signal(int n) +{ + // The condition must be locked before calling AICondition::signal or AICondition::broadcast. + llassert(mutex().isSelfLocked()); + // Signal n state machines. + while (n > 0 && !mWaitingStateMachines.empty()) + { + LLPointer state_machine = mWaitingStateMachines.front(); + bool success = state_machine->signalled(); + // Only state machines that are actually still blocked should be in the queue: + // they are removed from the queue by calling AICondition::remove whenever + // they are unblocked for whatever reason... + llassert(success); + if (success) + { + ++n; + } + else + { + // We never get here... + remove(state_machine.get()); + } + } +} + diff --git a/indra/aistatemachine/aicondition.h b/indra/aistatemachine/aicondition.h new file mode 100644 index 000000000..05dd9ea42 --- /dev/null +++ b/indra/aistatemachine/aicondition.h @@ -0,0 +1,110 @@ +/** + * @file aicondition.h + * @brief Condition variable for statemachines. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 14/10/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AICONDITION_H +#define AICONDITION_H + +#include +#include +#include "aithreadsafe.h" + +class AIStateMachine; +class LLMutex; + +// class AICondition +// +// Call AIStateMachine::wait(AICondition&) in the multiplex_impl of a state machine to +// make the state machine go idle until some thread calls AICondition::signal(). +// +// If the state machine is no longer running or wasn't waiting anymore because +// something else woke it up, then AICondition::signal() will wake up another +// state machine (if any). +// +// Usage: +// +// struct Foo { bool met(); }; // Returns true when the condition is met. +// AICondition Condition_t; +// AIAccess Condition_wat; +// +// // Some thread-safe condition variable. +// Condition_t condition; +// +// // Inside the state machine: +// { +// ... +// state WAIT_FOR_CONDITION: +// { +// // Lock condition and check it. Wait if condition is not met yet. +// { +// Condition_wat condition_w(condition); +// if (!condition_w->met()) +// { +// wait(condition); +// break; +// } +// } +// set_state(CONDITION_MET); +// break; +// } +// CONDITION_MET: +// { +// + +class AIConditionBase +{ + public: + virtual ~AIConditionBase() { } + + void signal(int n = 1); // Call this when the condition was met to release n state machines. + void broadcast(void) { signal(mWaitingStateMachines.size()); } // Release all blocked state machines. + + private: + // These functions are called by AIStateMachine. + friend class AIStateMachine; + void wait(AIStateMachine* state_machine); + void remove(AIStateMachine* state_machine); + + protected: + virtual LLMutex& mutex(void) = 0; + + protected: + typedef std::deque > queue_t; + queue_t mWaitingStateMachines; +}; + +template +class AICondition : public AIThreadSafeSimpleDC, public AIConditionBase +{ + protected: + /*virtual*/ LLMutex& mutex(void) { return this->mMutex; } +}; + +#endif + diff --git a/indra/aistatemachine/aistatemachine.cpp b/indra/aistatemachine/aistatemachine.cpp index bf867fffd..fcdb2d9c8 100644 --- a/indra/aistatemachine/aistatemachine.cpp +++ b/indra/aistatemachine/aistatemachine.cpp @@ -33,6 +33,7 @@ #include "linden_common.h" #include "aistatemachine.h" +#include "aicondition.h" #include "lltimer.h" //================================================================== @@ -283,7 +284,7 @@ char const* HelloWorld::state_str_impl(state_type run_state) const void AIEngine::add(AIStateMachine* state_machine) { - Dout(dc::statemachine, "Adding state machine [" << (void*)state_machine << "] to " << mName); + Dout(dc::statemachine(state_machine->mSMDebug), "Adding state machine [" << (void*)state_machine << "] to " << mName); engine_state_type_wat engine_state_w(mEngineState); engine_state_w->list.push_back(QueueElement(state_machine)); if (engine_state_w->waiting) @@ -330,7 +331,7 @@ void AIEngine::mainloop(void) engine_state_type_wat engine_state_w(mEngineState); if (!active) { - Dout(dc::statemachine, "Erasing state machine [" << (void*)&state_machine << "] from " << mName); + Dout(dc::statemachine(state_machine.mSMDebug), "Erasing state machine [" << (void*)&state_machine << "] from " << mName); engine_state_w->list.erase(queued_element++); } else @@ -392,7 +393,7 @@ void AIStateMachine::multiplex(event_type event) // If this fails then you are using a pointer to a state machine instead of an LLPointer. llassert(event == initial_run || getNumRefs() > 0); - DoutEntering(dc::statemachine, "AIStateMachine::multiplex(" << event_str(event) << ") [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::multiplex(" << event_str(event) << ") [" << (void*)this << "]"); base_state_type state; state_type run_state; @@ -407,7 +408,7 @@ void AIStateMachine::multiplex(event_type event) llassert(!mMultiplexMutex.isSelfLocked()); // We may never enter recursively! if (!mMultiplexMutex.tryLock()) { - Dout(dc::statemachine, "Leaving because it is already being run [" << (void*)this << "]"); + Dout(dc::statemachine(mSMDebug), "Leaving because it is already being run [" << (void*)this << "]"); return; } @@ -421,7 +422,7 @@ void AIStateMachine::multiplex(event_type event) // we should indeed run, again. if (event == schedule_run && !sub_state_type_rat(mSubState)->need_run) { - Dout(dc::statemachine, "Leaving because it was already being run [" << (void*)this << "]"); + Dout(dc::statemachine(mSMDebug), "Leaving because it was already being run [" << (void*)this << "]"); return; } @@ -440,9 +441,9 @@ void AIStateMachine::multiplex(event_type event) { #ifdef CWDEBUG if (state == bs_multiplex) - Dout(dc::statemachine, "Running state bs_multiplex / " << state_str_impl(run_state) << " [" << (void*)this << "]"); + Dout(dc::statemachine(mSMDebug), "Running state bs_multiplex / " << state_str_impl(run_state) << " [" << (void*)this << "]"); else - Dout(dc::statemachine, "Running state " << state_str(state) << " [" << (void*)this << "]"); + Dout(dc::statemachine(mSMDebug), "Running state " << state_str(state) << " [" << (void*)this << "]"); #endif #ifdef SHOW_ASSERT @@ -503,7 +504,7 @@ void AIStateMachine::multiplex(event_type event) // run of bs_reset is not a problem because it happens to be a NoOp. state = (state == bs_initialize) ? bs_reset : bs_abort; #ifdef CWDEBUG - Dout(dc::statemachine, "Late abort detected! Running state " << state_str(state) << " instead [" << (void*)this << "]"); + Dout(dc::statemachine(mSMDebug), "Late abort detected! Running state " << state_str(state) << " instead [" << (void*)this << "]"); #endif } #ifdef SHOW_ASSERT @@ -665,7 +666,7 @@ void AIStateMachine::multiplex(event_type event) #ifdef CWDEBUG if (state != state_w->base_state) - Dout(dc::statemachine, "Base state changed from " << state_str(state) << " to " << state_str(state_w->base_state) << + Dout(dc::statemachine(mSMDebug), "Base state changed from " << state_str(state) << " to " << state_str(state_w->base_state) << "; need_new_run = " << (need_new_run ? "true" : "false") << " [" << (void*)this << "]"); #endif } @@ -699,11 +700,15 @@ void AIStateMachine::multiplex(event_type event) // Mark that we're added to this engine, and at the same time, that we're not added to the previous one. state_w->current_engine = engine; } +#ifdef SHOW_ASSERT + // We are leaving the loop, but we're not idle. The statemachine should re-enter the loop again. + mDebugShouldRun = true; +#endif } else { - // Remove this state machine from any engine. - // Cause the engine to remove us. + // Remove this state machine from any engine, + // causing the engine to remove us. state_w->current_engine = NULL; } @@ -749,7 +754,7 @@ void AIStateMachine::multiplex(event_type event) AIStateMachine::state_type AIStateMachine::begin_loop(base_state_type base_state) { - DoutEntering(dc::statemachine, "AIStateMachine::begin_loop(" << state_str(base_state) << ") [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::begin_loop(" << state_str(base_state) << ") [" << (void*)this << "]"); sub_state_type_wat sub_state_w(mSubState); // Honor a subsequent call to idle() (only necessary in bs_multiplex, but it doesn't hurt to reset this flag in other states too). @@ -759,7 +764,7 @@ AIStateMachine::state_type AIStateMachine::begin_loop(base_state_type base_state // Honor previous calls to advance_state() (once run_state is initialized). if (base_state == bs_multiplex && sub_state_w->advance_state > sub_state_w->run_state) { - Dout(dc::statemachine, "Copying advance_state to run_state, because it is larger [" << state_str_impl(sub_state_w->advance_state) << " > " << state_str_impl(sub_state_w->run_state) << "]"); + Dout(dc::statemachine(mSMDebug), "Copying advance_state to run_state, because it is larger [" << state_str_impl(sub_state_w->advance_state) << " > " << state_str_impl(sub_state_w->run_state) << "]"); sub_state_w->run_state = sub_state_w->advance_state; } #ifdef SHOW_ASSERT @@ -789,7 +794,7 @@ AIStateMachine::state_type AIStateMachine::begin_loop(base_state_type base_state void AIStateMachine::run(AIStateMachine* parent, state_type new_parent_state, bool abort_parent, bool on_abort_signal_parent, AIEngine* default_engine) { - DoutEntering(dc::statemachine, "AIStateMachine::run(" << + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::run(" << (void*)parent << ", " << (parent ? parent->state_str_impl(new_parent_state) : "NA") << ", abort_parent = " << (abort_parent ? "true" : "false") << @@ -839,7 +844,7 @@ void AIStateMachine::run(AIStateMachine* parent, state_type new_parent_state, bo void AIStateMachine::run(callback_type::signal_type::slot_type const& slot, AIEngine* default_engine) { - DoutEntering(dc::statemachine, "AIStateMachine::run(, default_engine = " << default_engine->name() << ") [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::run(, default_engine = " << default_engine->name() << ") [" << (void*)this << "]"); #ifdef SHOW_ASSERT { @@ -874,7 +879,7 @@ void AIStateMachine::run(callback_type::signal_type::slot_type const& slot, AIEn void AIStateMachine::callback(void) { - DoutEntering(dc::statemachine, "AIStateMachine::callback() [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::callback() [" << (void*)this << "]"); bool aborted = sub_state_type_rat(mSubState)->aborted; if (mParent) @@ -920,7 +925,7 @@ void AIStateMachine::force_killed(void) void AIStateMachine::kill(void) { - DoutEntering(dc::statemachine, "AIStateMachine::kill() [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::kill() [" << (void*)this << "]"); #ifdef SHOW_ASSERT { multiplex_state_type_rat state_r(mState); @@ -937,7 +942,7 @@ void AIStateMachine::kill(void) void AIStateMachine::reset() { - DoutEntering(dc::statemachine, "AIStateMachine::reset() [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::reset() [" << (void*)this << "]"); #ifdef SHOW_ASSERT mDebugAborted = false; mDebugContPending = false; @@ -960,6 +965,8 @@ void AIStateMachine::reset() sub_state_w->reset = true; // Start running. sub_state_w->idle = false; + // We're not waiting for a condition. + sub_state_w->blocked = NULL; // Keep running till we reach at least bs_multiplex. sub_state_w->need_run = true; } @@ -972,7 +979,7 @@ void AIStateMachine::reset() void AIStateMachine::set_state(state_type new_state) { - DoutEntering(dc::statemachine, "AIStateMachine::set_state(" << state_str_impl(new_state) << ") [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::set_state(" << state_str_impl(new_state) << ") [" << (void*)this << "]"); #ifdef SHOW_ASSERT { multiplex_state_type_rat state_r(mState); @@ -983,6 +990,8 @@ void AIStateMachine::set_state(state_type new_state) } #endif sub_state_type_wat sub_state_w(mSubState); + // It should never happen that set_state() is called while we're blocked. + llassert(!sub_state_w->blocked); // Force current state to the requested state. sub_state_w->run_state = new_state; // Void last call to advance_state. @@ -999,13 +1008,13 @@ void AIStateMachine::set_state(state_type new_state) void AIStateMachine::advance_state(state_type new_state) { - DoutEntering(dc::statemachine, "AIStateMachine::advance_state(" << state_str_impl(new_state) << ") [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::advance_state(" << state_str_impl(new_state) << ") [" << (void*)this << "]"); { sub_state_type_wat sub_state_w(mSubState); // Ignore call to advance_state when the currently queued state is already greater or equal to the requested state. if (sub_state_w->advance_state >= new_state) { - Dout(dc::statemachine, "Ignored, because " << state_str_impl(sub_state_w->advance_state) << " >= " << state_str_impl(new_state) << "."); + Dout(dc::statemachine(mSMDebug), "Ignored, because " << state_str_impl(sub_state_w->advance_state) << " >= " << state_str_impl(new_state) << "."); return; } // Ignore call to advance_state when the current state is greater than the requested state: the new state would be @@ -1014,7 +1023,7 @@ void AIStateMachine::advance_state(state_type new_state) // the state change is and should be being ignored: the statemachine would start running it's current state (again). if (sub_state_w->run_state > new_state) { - Dout(dc::statemachine, "Ignored, because " << state_str_impl(sub_state_w->run_state) << " > " << state_str_impl(new_state) << " (current state)."); + Dout(dc::statemachine(mSMDebug), "Ignored, because " << state_str_impl(sub_state_w->run_state) << " > " << state_str_impl(new_state) << " (current state)."); return; } // Increment state. @@ -1023,6 +1032,13 @@ void AIStateMachine::advance_state(state_type new_state) sub_state_w->idle = false; // Ignore a call to idle if it occurs before we leave multiplex_impl(). sub_state_w->skip_idle = true; + // No longer say we woke up when signalled() is called. + if (sub_state_w->blocked) + { + Dout(dc::statemachine(mSMDebug), "Removing statemachine from condition " << (void*)sub_state_w->blocked); + sub_state_w->blocked->remove(this); + sub_state_w->blocked = NULL; + } // Mark that a re-entry of multiplex() is necessary. sub_state_w->need_run = true; #ifdef SHOW_ASSERT @@ -1048,7 +1064,7 @@ void AIStateMachine::advance_state(state_type new_state) void AIStateMachine::idle(void) { - DoutEntering(dc::statemachine, "AIStateMachine::idle() [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::idle() [" << (void*)this << "]"); #ifdef SHOW_ASSERT { multiplex_state_type_rat state_r(mState); @@ -1066,7 +1082,7 @@ void AIStateMachine::idle(void) // Ignore call to idle() when advance_state() was called since last call to set_state(). if (sub_state_w->skip_idle) { - Dout(dc::statemachine, "Ignored, because skip_idle is true (advance_state() was called last)."); + Dout(dc::statemachine(mSMDebug), "Ignored, because skip_idle is true (advance_state() was called last)."); return; } // Mark that we are idle. @@ -1075,13 +1091,54 @@ void AIStateMachine::idle(void) mSleep = 0; } +// This function is very much like idle(). +void AIStateMachine::wait(AIConditionBase& condition) +{ + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::wait(" << (void*)&condition << ") [" << (void*)this << "]"); +#ifdef SHOW_ASSERT + { + multiplex_state_type_rat state_r(mState); + // wait() may only be called multiplex_impl(). + llassert(state_r->base_state == bs_multiplex); + // May only be called by the thread that is holding mMultiplexMutex. + llassert(mThreadId.equals_current_thread()); + } + // wait() following set_state() cancels the reason to run because of the call to set_state. + mDebugSetStatePending = false; +#endif + sub_state_type_wat sub_state_w(mSubState); + // As wait() may only be called from within the state machine, it should never happen that the state machine is already idle. + llassert(!sub_state_w->idle); + // Ignore call to wait() when advance_state() was called since last call to set_state(). + if (sub_state_w->skip_idle) + { + Dout(dc::statemachine(mSMDebug), "Ignored, because skip_idle is true (advance_state() was called last)."); + return; + } + // Register ourselves with the condition object. + condition.wait(this); + // Mark that we are idle. + sub_state_w->idle = true; + // Mark that we are waiting for a condition. + sub_state_w->blocked = &condition; + // Not sleeping (anymore). + mSleep = 0; +} + void AIStateMachine::cont(void) { - DoutEntering(dc::statemachine, "AIStateMachine::cont() [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::cont() [" << (void*)this << "]"); { sub_state_type_wat sub_state_w(mSubState); // Void last call to idle(), if any. sub_state_w->idle = false; + // No longer say we woke up when signalled() is called. + if (sub_state_w->blocked) + { + Dout(dc::statemachine(mSMDebug), "Removing statemachine from condition " << (void*)sub_state_w->blocked); + sub_state_w->blocked->remove(this); + sub_state_w->blocked = NULL; + } // Mark that a re-entry of multiplex() is necessary. sub_state_w->need_run = true; #ifdef SHOW_ASSERT @@ -1095,15 +1152,56 @@ void AIStateMachine::cont(void) } } +// This function is very much like cont(), except that it has no effect when we are not in a blocked state. +// Returns true if the state machine was unblocked, false if it was already unblocked. +bool AIStateMachine::signalled(void) +{ + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::signalled() [" << (void*)this << "]"); + { + sub_state_type_wat sub_state_w(mSubState); + // Test if we are blocked or not. + if (sub_state_w->blocked) + { + Dout(dc::statemachine(mSMDebug), "Removing statemachine from condition " << (void*)sub_state_w->blocked); + sub_state_w->blocked->remove(this); + sub_state_w->blocked = NULL; + } + else + { + return false; + } + // Void last call to wait(). + sub_state_w->idle = false; + // Mark that a re-entry of multiplex() is necessary. + sub_state_w->need_run = true; +#ifdef SHOW_ASSERT + // From this moment. + mDebugContPending = true; +#endif + } + if (!mMultiplexMutex.isSelfLocked()) + { + multiplex(schedule_run); + } + return true; +} + void AIStateMachine::abort(void) { - DoutEntering(dc::statemachine, "AIStateMachine::abort() [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::abort() [" << (void*)this << "]"); bool is_waiting = false; { multiplex_state_type_rat state_r(mState); sub_state_type_wat sub_state_w(mSubState); // Mark that we are aborted, iff we didn't already finish. sub_state_w->aborted = !sub_state_w->finished; + // No longer say we woke up when signalled() is called. + if (sub_state_w->blocked) + { + Dout(dc::statemachine(mSMDebug), "Removing statemachine from condition " << (void*)sub_state_w->blocked); + sub_state_w->blocked->remove(this); + sub_state_w->blocked = NULL; + } // Mark that a re-entry of multiplex() is necessary. sub_state_w->need_run = true; // Schedule a new run when this state machine is waiting. @@ -1128,7 +1226,7 @@ void AIStateMachine::abort(void) void AIStateMachine::finish(void) { - DoutEntering(dc::statemachine, "AIStateMachine::finish() [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::finish() [" << (void*)this << "]"); #ifdef SHOW_ASSERT { multiplex_state_type_rat state_r(mState); @@ -1147,7 +1245,7 @@ void AIStateMachine::finish(void) void AIStateMachine::yield(void) { - DoutEntering(dc::statemachine, "AIStateMachine::yield() [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::yield() [" << (void*)this << "]"); multiplex_state_type_rat state_r(mState); // yield() may only be called from multiplex_impl(). llassert(state_r->base_state == bs_multiplex); @@ -1160,7 +1258,7 @@ void AIStateMachine::yield(void) void AIStateMachine::yield(AIEngine* engine) { llassert(engine); - DoutEntering(dc::statemachine, "AIStateMachine::yield(" << engine->name() << ") [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::yield(" << engine->name() << ") [" << (void*)this << "]"); #ifdef SHOW_ASSERT { multiplex_state_type_rat state_r(mState); @@ -1173,9 +1271,19 @@ void AIStateMachine::yield(AIEngine* engine) mYieldEngine = engine; } +bool AIStateMachine::yield_if_not(AIEngine* engine) +{ + if (engine && multiplex_state_type_rat(mState)->current_engine != engine) + { + yield(engine); + return true; + } + return false; +} + void AIStateMachine::yield_frame(unsigned int frames) { - DoutEntering(dc::statemachine, "AIStateMachine::yield_frame(" << frames << ") [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::yield_frame(" << frames << ") [" << (void*)this << "]"); mSleep = -(S64)frames; // Sleeping is always done from the main thread. yield(&gMainThreadEngine); @@ -1183,7 +1291,7 @@ void AIStateMachine::yield_frame(unsigned int frames) void AIStateMachine::yield_ms(unsigned int ms) { - DoutEntering(dc::statemachine, "AIStateMachine::yield_ms(" << ms << ") [" << (void*)this << "]"); + DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::yield_ms(" << ms << ") [" << (void*)this << "]"); mSleep = get_clock_count() + calc_clock_frequency() * ms / 1000; // Sleeping is always done from the main thread. yield(&gMainThreadEngine); @@ -1233,7 +1341,7 @@ void AIEngine::threadloop(void) engine_state_type_wat engine_state_w(mEngineState); if (!active) { - Dout(dc::statemachine, "Erasing state machine [" << (void*)&state_machine << "] from " << mName); + Dout(dc::statemachine(state_machine.mSMDebug), "Erasing state machine [" << (void*)&state_machine << "] from " << mName); engine_state_w->list.erase(queued_element++); } else diff --git a/indra/aistatemachine/aistatemachine.h b/indra/aistatemachine/aistatemachine.h index 2b019c91f..047fe0515 100644 --- a/indra/aistatemachine/aistatemachine.h +++ b/indra/aistatemachine/aistatemachine.h @@ -39,6 +39,7 @@ #include #include +class AIConditionBase; class AIStateMachine; class AIEngine @@ -132,6 +133,7 @@ class AIStateMachine : public LLThreadSafeRefCount struct sub_state_type { state_type run_state; state_type advance_state; + AIConditionBase* blocked; bool reset; bool need_run; bool idle; @@ -195,20 +197,36 @@ class AIStateMachine : public LLThreadSafeRefCount bool mDebugAdvanceStatePending; // True while advance_state() was called by not handled yet. bool mDebugRefCalled; // True when ref() is called (or will be called within the critial area of mMultiplexMutex). #endif +#ifdef CWDEBUG + protected: + bool mSMDebug; // Print debug output only when true. +#endif + private: U64 mRuntime; // Total time spent running in the main thread (in clocks). public: - AIStateMachine(void) : mCallback(NULL), mDefaultEngine(NULL), mYieldEngine(NULL), + AIStateMachine(CWD_ONLY(bool debug)) : mCallback(NULL), mDefaultEngine(NULL), mYieldEngine(NULL), #ifdef SHOW_ASSERT mThreadId(AIThreadID::none), mDebugLastState(bs_killed), mDebugShouldRun(false), mDebugAborted(false), mDebugContPending(false), mDebugSetStatePending(false), mDebugAdvanceStatePending(false), mDebugRefCalled(false), +#endif +#ifdef CWDEBUG + mSMDebug(debug), #endif mRuntime(0) { } protected: - // The user should call finish() (or abort(), or kill() from the call back when finish_impl() calls run()), not delete a class derived from AIStateMachine directly. - virtual ~AIStateMachine() { llassert(multiplex_state_type_rat(mState)->base_state == bs_killed); } + // The user should call finish() (or abort(), or kill() from the call back when finish_impl() calls run()), + // not delete a class derived from AIStateMachine directly. Deleting it directly before calling run() is + // ok however. + virtual ~AIStateMachine() + { +#ifdef SHOW_ASSERT + base_state_type state = multiplex_state_type_rat(mState)->base_state; + llassert(state == bs_killed || state == bs_reset); +#endif + } public: // These functions may be called directly after creation, or from within finish_impl(), or from the call back function. @@ -224,11 +242,13 @@ class AIStateMachine : public LLThreadSafeRefCount void set_state(state_type new_state); // Run this state the NEXT loop. // These functions can only be called from within multiplex_impl(). void idle(void); // Go idle unless cont() or advance_state() were called since the start of the current loop, or until they are called. + void wait(AIConditionBase& condition); // The same as idle(), but wake up when AICondition::signal() is called. void finish(void); // Mark that the state machine finished and schedule the call back. void yield(void); // Yield to give CPU to other state machines, but do not go idle. void yield(AIEngine* engine); // Yield to give CPU to other state machines, but do not go idle. Continue running from engine 'engine'. void yield_frame(unsigned int frames); // Run from the main-thread engine after at least 'frames' frames have passed. void yield_ms(unsigned int ms); // Run from the main-thread engine after roughly 'ms' miliseconds have passed. + bool yield_if_not(AIEngine* engine); // Do not really yield, unless the current engine is not 'engine'. Returns true if it switched engine. public: // This function can be called from multiplex_imp(), but also by a child state machine and @@ -236,11 +256,12 @@ class AIStateMachine : public LLThreadSafeRefCount // to access this state machine. void abort(void); // Abort the state machine (unsuccessful finish). - // These are the only two functions that can be called by any thread at any moment. + // These are the only three functions that can be called by any thread at any moment. // Those threads should use an LLPointer to access this state machine. void cont(void); // Guarantee at least one full run of multiplex() after this function is called. Cancels the last call to idle(). void advance_state(state_type new_state); // Guarantee at least one full run of multiplex() after this function is called // iff new_state is larger than the last state that was processed. + bool signalled(void); // Call cont() iff this state machine is still blocked after a call to wait(). Returns false if it already unblocked. public: // Accessors. diff --git a/indra/aistatemachine/aistatemachinethread.h b/indra/aistatemachine/aistatemachinethread.h index 780060bb6..2891cbb77 100644 --- a/indra/aistatemachine/aistatemachinethread.h +++ b/indra/aistatemachine/aistatemachinethread.h @@ -181,7 +181,11 @@ class AIStateMachineThreadBase : public AIStateMachine { static state_type const max_state = wait_stopped + 1; protected: - AIStateMachineThreadBase(void) { } + AIStateMachineThreadBase(CWD_ONLY(bool debug)) +#ifdef CWDEBUG + : AIStateMachine(debug) +#endif + { } private: // Handle initializing the object. @@ -217,7 +221,10 @@ class AIStateMachineThread : public AIStateMachineThreadBase { public: // Constructor. - AIStateMachineThread(void) + AIStateMachineThread(CWD_ONLY(bool debug)) +#ifdef CWDEBUG + : AIStateMachineThreadBase(debug) +#endif { *AIThreadImpl::StateMachineThread_wat(mThreadImpl.mStateMachineThread) = this; } diff --git a/indra/aistatemachine/aitimer.h b/indra/aistatemachine/aitimer.h index 5b028c6e0..3ee510007 100644 --- a/indra/aistatemachine/aitimer.h +++ b/indra/aistatemachine/aitimer.h @@ -76,7 +76,11 @@ class AITimer : public AIStateMachine { F64 mInterval; //!< Input variable: interval after which the event will be generated, in seconds. public: - AITimer(void) : mInterval(0) { DoutEntering(dc::statemachine, "AITimer(void) [" << (void*)this << "]"); } + AITimer(CWD_ONLY(bool debug = false)) : +#ifdef CWDEBUG + AIStateMachine(debug), +#endif + mInterval(0) { DoutEntering(dc::statemachine(mSMDebug), "AITimer(void) [" << (void*)this << "]"); } /** * @brief Set the interval after which the timer should expire. @@ -96,7 +100,7 @@ class AITimer : public AIStateMachine { protected: // Call finish() (or abort()), not delete. - /*virtual*/ ~AITimer() { DoutEntering(dc::statemachine, "~AITimer() [" << (void*)this << "]"); mFrameTimer.cancel(); } + /*virtual*/ ~AITimer() { DoutEntering(dc::statemachine(mSMDebug), "~AITimer() [" << (void*)this << "]"); mFrameTimer.cancel(); } // Handle initializing the object. /*virtual*/ void initialize_impl(void); diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index a45c07f69..c2458b098 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -46,6 +46,10 @@ if (WINDOWS) set(MSVC_DIR 10.0) set(MSVC_SUFFIX 100) endif (MSVC10) + if (MSVC11) + set(MSVC_DIR 11.0) + set(MSVC_SUFFIX 110) + endif (MSVC11) # Remove default /Zm1000 flag that cmake inserts string (REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") @@ -78,11 +82,17 @@ if (WINDOWS) /W3 /c /Zc:forScope - /Zc:wchar_t- + /Zc:wchar_t- /nologo /Oy- - /arch:SSE2 ) + + # SSE2 is implied on win64 + if(WORD_SIZE EQUAL 32) + add_definitions(/arch:SSE2) + else(WORD_SIZE EQUAL 32) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /wd4267 /wd4250 /wd4244") + endif(WORD_SIZE EQUAL 32) # configure win32 API for windows XP+ compatibility set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)") diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 5ff1b0399..d2e9f2249 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -81,6 +81,7 @@ set(cmake_SOURCE_FILES Linking.cmake MediaPluginBase.cmake NDOF.cmake + NVAPI.cmake OPENAL.cmake OpenGL.cmake OpenJPEG.cmake diff --git a/indra/cmake/CopyWinLibs.cmake b/indra/cmake/CopyWinLibs.cmake index 9d52499a1..afd4d31f7 100644 --- a/indra/cmake/CopyWinLibs.cmake +++ b/indra/cmake/CopyWinLibs.cmake @@ -6,6 +6,14 @@ include(CMakeCopyIfDifferent) +if(WORD_SIZE EQUAL 32) + set(debug_libs_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") + set(release_libs_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") +else(WORD_SIZE EQUAL 32) + set(debug_libs_dir "${CMAKE_SOURCE_DIR}/../libraries/x86_64-win/lib/debug") + set(release_libs_dir "${CMAKE_SOURCE_DIR}/../libraries/x86_64-win/lib/release") +endif(WORD_SIZE EQUAL 32) + set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-win32") set(vivox_files SLVoice.exe @@ -23,7 +31,7 @@ copy_if_different( set(all_targets ${all_targets} ${out_targets}) -set(debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") +set(debug_src_dir "${debug_libs_dir}") set(debug_files libhunspell.dll libapr-1.dll @@ -44,7 +52,7 @@ copy_if_different( set(all_targets ${all_targets} ${out_targets}) # Debug config runtime files required for the plugin test mule -set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") +set(plugintest_debug_src_dir "${debug_libs_dir}") set(plugintest_debug_files libeay32.dll qtcored4.dll @@ -63,7 +71,7 @@ copy_if_different( set(all_targets ${all_targets} ${out_targets}) # Debug config runtime files required for the plugin test mule (Qt image format plugins) -set(plugintest_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug/imageformats") +set(plugintest_debug_src_dir "${debug_libs_dir}/imageformats") set(plugintest_debug_files qgifd4.dll qicod4.dll @@ -89,7 +97,7 @@ copy_if_different( set(all_targets ${all_targets} ${out_targets}) # Release & ReleaseDebInfo config runtime files required for the plugin test mule -set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") +set(plugintest_release_src_dir "${release_libs_dir}") set(plugintest_release_files libeay32.dll qtcore4.dll @@ -116,7 +124,7 @@ copy_if_different( set(all_targets ${all_targets} ${out_targets}) # Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt image format plugins) -set(plugintest_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release/imageformats") +set(plugintest_release_src_dir "${release_libs_dir}/imageformats") set(plugintest_release_files qgif4.dll qico4.dll @@ -158,7 +166,7 @@ copy_if_different( set(all_targets ${all_targets} ${out_targets}) # Debug config runtime files required for the plugins -set(plugins_debug_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug") +set(plugins_debug_src_dir "${debug_libs_dir}") set(plugins_debug_files libeay32.dll qtcored4.dll @@ -177,7 +185,7 @@ copy_if_different( set(all_targets ${all_targets} ${out_targets}) # Release & ReleaseDebInfo config runtime files required for the plugins -set(plugins_release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") +set(plugins_release_src_dir "${release_libs_dir}") set(plugins_release_files libeay32.dll qtcore4.dll @@ -203,9 +211,9 @@ copy_if_different( ) set(all_targets ${all_targets} ${out_targets}) -set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release") + +set(release_src_dir "${release_libs_dir}") set(release_files - libtcmalloc_minimal.dll libhunspell.dll libapr-1.dll libaprutil-1.dll @@ -216,8 +224,21 @@ set(release_files glod.dll ) +if(WORD_SIZE EQUAL 32) + set(release_files ${release_files} + libtcmalloc_minimal.dll + ) +endif(WORD_SIZE EQUAL 32) + + if(FMODEX) - find_path(FMODEX_BINARY_DIR fmodex.dll + if (WORD_SIZE EQUAL 32) + set(fmodex_dll_file "fmodex.dll") + else (WORD_SIZE EQUAL 32) + set(fmodex_dll_file "fmodex64.dll") + endif (WORD_SIZE EQUAL 32) + + find_path(FMODEX_BINARY_DIR "${fmodex_dll_file}" "${release_src_dir}" "${FMODEX_SDK_DIR}/api" "${FMODEX_SDK_DIR}" @@ -225,11 +246,11 @@ if(FMODEX) ) if(FMODEX_BINARY_DIR) - copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/Release" out_targets fmodex.dll) + copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/Release" out_targets "${fmodex_dll_file}") set(all_targets ${all_targets} ${out_targets}) - copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo" out_targets fmodex.dll) + copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo" out_targets "${fmodex_dll_file}") set(all_targets ${all_targets} ${out_targets}) - copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/Debug" out_targets fmodex.dll) + copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/Debug" out_targets "${fmodex_dll_file}") set(all_targets ${all_targets} ${out_targets}) endif(FMODEX_BINARY_DIR) endif(FMODEX) @@ -285,105 +306,6 @@ copy_if_different( ) set(all_targets ${all_targets} ${out_targets}) -# Copy MS C runtime dlls, required for packaging. -# *TODO - Adapt this to support VC9 -if (MSVC80) - FIND_PATH(debug_msvc8_redist_path msvcr80d.dll - PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VC;ProductDir]/redist/Debug_NonRedist/x86/Microsoft.VC80.DebugCRT - NO_DEFAULT_PATH - NO_DEFAULT_PATH - ) - - if(EXISTS ${debug_msvc8_redist_path}) - set(debug_msvc8_files - msvcr80d.dll - msvcp80d.dll - Microsoft.VC80.DebugCRT.manifest - ) - - copy_if_different( - ${debug_msvc8_redist_path} - "${CMAKE_CURRENT_BINARY_DIR}/Debug" - out_targets - ${debug_msvc8_files} - ) - set(all_targets ${all_targets} ${out_targets}) - - set(debug_appconfig_file ${CMAKE_CURRENT_BINARY_DIR}/Debug/${VIEWER_BINARY_NAME}.exe.config) - add_custom_command( - OUTPUT ${debug_appconfig_file} - COMMAND ${PYTHON_EXECUTABLE} - ARGS - ${CMAKE_CURRENT_SOURCE_DIR}/build_win32_appConfig.py - ${CMAKE_CURRENT_BINARY_DIR}/Debug/Microsoft.VC80.DebugCRT.manifest - ${CMAKE_CURRENT_SOURCE_DIR}/SecondLifeDebug.exe.config - ${debug_appconfig_file} - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Debug/Microsoft.VC80.DebugCRT.manifest - COMMENT "Creating debug app config file" - ) - - endif (EXISTS ${debug_msvc8_redist_path}) - - FIND_PATH(release_msvc8_redist_path msvcr80.dll - PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VC;ProductDir]/redist/x86/Microsoft.VC80.CRT - NO_DEFAULT_PATH - NO_DEFAULT_PATH - ) - - if(EXISTS ${release_msvc8_redist_path}) - set(release_msvc8_files - msvcr80.dll - msvcp80.dll - Microsoft.VC80.CRT.manifest - ) - - copy_if_different( - ${release_msvc8_redist_path} - "${CMAKE_CURRENT_BINARY_DIR}/Release" - out_targets - ${release_msvc8_files} - ) - set(all_targets ${all_targets} ${out_targets}) - - copy_if_different( - ${release_msvc8_redist_path} - "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo" - out_targets - ${release_msvc8_files} - ) - set(all_targets ${all_targets} ${out_targets}) - - set(release_appconfig_file ${CMAKE_CURRENT_BINARY_DIR}/Release/${VIEWER_BINARY_NAME}.exe.config) - add_custom_command( - OUTPUT ${release_appconfig_file} - COMMAND ${PYTHON_EXECUTABLE} - ARGS - ${CMAKE_CURRENT_SOURCE_DIR}/build_win32_appConfig.py - ${CMAKE_CURRENT_BINARY_DIR}/Release/Microsoft.VC80.CRT.manifest - ${CMAKE_CURRENT_SOURCE_DIR}/SecondLife.exe.config - ${release_appconfig_file} - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Release/Microsoft.VC80.CRT.manifest - COMMENT "Creating release app config file" - ) - - set(relwithdebinfo_appconfig_file ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/${VIEWER_BINARY_NAME}.exe.config) - add_custom_command( - OUTPUT ${relwithdebinfo_appconfig_file} - COMMAND ${PYTHON_EXECUTABLE} - ARGS - ${CMAKE_CURRENT_SOURCE_DIR}/build_win32_appConfig.py - ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/Microsoft.VC80.CRT.manifest - ${CMAKE_CURRENT_SOURCE_DIR}/SecondLife.exe.config - ${relwithdebinfo_appconfig_file} - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/Microsoft.VC80.CRT.manifest - COMMENT "Creating relwithdebinfo app config file" - ) - - endif (EXISTS ${release_msvc8_redist_path}) -endif (MSVC80) - add_custom_target(copy_win_libs ALL DEPENDS ${all_targets} diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake index a0dc4b2b5..97a0bf910 100644 --- a/indra/cmake/DirectX.cmake +++ b/indra/cmake/DirectX.cmake @@ -44,10 +44,15 @@ if (WINDOWS) "$ENV{ProgramFiles(x86)}/Windows Kits/8.0" ) - if (WIN_KIT_ROOT_DIR) + find_path (WIN_KIT_LIB_DIR dxguid.lib + "${WIN_KIT_ROOT_DIR}/Lib/winv6.3/um/${DIRECTX_ARCHITECTURE}" + "${WIN_KIT_ROOT_DIR}/Lib/Win8/um/${DIRECTX_ARCHITECTURE}" + ) + + if (WIN_KIT_ROOT_DIR AND WIN_KIT_LIB_DIR) set (DIRECTX_INCLUDE_DIR "${WIN_KIT_ROOT_DIR}/Include/um" "${WIN_KIT_ROOT_DIR}/Include/shared") - set (DIRECTX_LIBRARY_DIR "${WIN_KIT_ROOT_DIR}/Lib/Win8/um/${DIRECTX_ARCHITECTURE}") - endif (WIN_KIT_ROOT_DIR) + set (DIRECTX_LIBRARY_DIR "${WIN_KIT_LIB_DIR}") + endif (WIN_KIT_ROOT_DIR AND WIN_KIT_LIB_DIR) endif (DIRECTX_ROOT_DIR) if (DIRECTX_INCLUDE_DIR) diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake index dbac0ebac..f3425f1b2 100644 --- a/indra/cmake/FMODEX.cmake +++ b/indra/cmake/FMODEX.cmake @@ -16,7 +16,7 @@ if (NOT FMODEX_LIBRARY) ) elseif(WORD_SIZE EQUAL 64) find_library(FMODEX_LIBRARY - fmodex64 fmodexL64 + fmodex64_vc fmodexL64_vc fmodex64 fmodexL64 PATHS "${FMODEX_SDK_DIR}/api/lib" "${FMODEX_SDK_DIR}/api" @@ -25,21 +25,31 @@ if (NOT FMODEX_LIBRARY) ) endif(WORD_SIZE EQUAL 32) endif(FMODEX_SDK_DIR) - if(WINDOWS AND NOT FMODEX_LIBRARY) - set(FMODEX_PROG_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows") - find_library(FMODEX_LIBRARY - fmodex_vc fmodexL_vc - PATHS - "${FMODEX_PROG_DIR}/api/lib" - "${FMODEX_PROG_DIR}/api" - "${FMODEX_PROG_DIR}" - ) + if(WINDOWS AND NOT FMODEX_SDK_DIR) + GET_FILENAME_COMPONENT(FMODEX_PROG_DIR [HKEY_CURRENT_USER\\Software\\FMOD\ Programmers\ API\ Windows] ABSOLUTE CACHE) + if(WORD_SIZE EQUAL 32) + find_library(FMODEX_LIBRARY + fmodex_vc fmodexL_vc + PATHS + "${FMODEX_PROG_DIR}/api/lib" + "${FMODEX_PROG_DIR}/api" + "${FMODEX_PROG_DIR}" + ) + else(WORD_SIZE EQUAL 32) + find_library(FMODEX_LIBRARY + fmodex64_vc fmodexL64_vc + PATHS + "${FMODEX_PROG_DIR}/api/lib" + "${FMODEX_PROG_DIR}/api" + "${FMODEX_PROG_DIR}" + ) + endif(WORD_SIZE EQUAL 32) if(FMODEX_LIBRARY) message(STATUS "Found fmodex in ${FMODEX_PROG_DIR}") set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}") set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}" CACHE PATH "Path to the FMOD Ex SDK." FORCE) endif(FMODEX_LIBRARY) - endif(WINDOWS AND NOT FMODEX_LIBRARY) + endif(WINDOWS AND NOT FMODEX_SDK_DIR) endif (NOT FMODEX_LIBRARY) find_path(FMODEX_INCLUDE_DIR fmod.hpp diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake index 00754ec36..e7bc897c9 100644 --- a/indra/cmake/Linking.cmake +++ b/indra/cmake/Linking.cmake @@ -5,22 +5,29 @@ set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") include(Variables) if (NOT STANDALONE) - if (WINDOWS) - set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib) - set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/release) - set(ARCH_PREBUILT_DIRS_DEBUG ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/debug) - elseif (LINUX) - set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/release) - set(ARCH_PREBUILT_DIRS_RELEASE ${ARCH_PREBUILT_DIRS}) - set(ARCH_PREBUILT_DIRS_DEBUG ${ARCH_PREBUILT_DIRS}) - elseif (DARWIN) - set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib) - set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/release) - set(ARCH_PREBUILT_DIRS_DEBUG ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/debug) - endif (WINDOWS) + set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib) + set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/release) + set(ARCH_PREBUILT_DIRS_DEBUG ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/debug) + + if(WINDOWS OR ${CMAKE_GENERATOR} MATCHES "Xcode") + # the cmake xcode and VS generators implicitly append ${CMAKE_CFG_INTDIR} to the library paths for us + # fortunately both windows and darwin are case insensitive filesystems so this works. + set(ARCH_PREBUILT_LINK_DIRS "${ARCH_PREBUILT_DIRS}") + else(WINDOWS OR ${CMAKE_GENERATOR} MATCHES "Xcode") + # else block is for linux and any other makefile based generators + string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) + set(ARCH_PREBUILT_LINK_DIRS ${ARCH_PREBUILT_DIRS}/${CMAKE_BUILD_TYPE_LOWER}) + endif(WINDOWS OR ${CMAKE_GENERATOR} MATCHES "Xcode") + + if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release") + # When we're building something other than Release, append the + # packages/lib/release directory to deal with autobuild packages that don't + # provide (e.g.) lib/debug libraries. + list(APPEND ARCH_PREBUILT_LINK_DIRS ${ARCH_PREBUILT_DIRS_RELEASE}) + endif (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release") endif (NOT STANDALONE) -link_directories(${ARCH_PREBUILT_DIRS}) +link_directories(${ARCH_PREBUILT_LINK_DIRS}) if (LINUX) set(DL_LIBRARY dl) diff --git a/indra/cmake/NVAPI.cmake b/indra/cmake/NVAPI.cmake new file mode 100644 index 000000000..d60e42c87 --- /dev/null +++ b/indra/cmake/NVAPI.cmake @@ -0,0 +1,21 @@ +# -*- cmake -*- +include(Prebuilt) +include(Variables) + +set(NVAPI ON CACHE BOOL "Use NVAPI.") + +if (NVAPI) + if (WINDOWS) + use_prebuilt_binary(nvapi) + if (WORD_SIZE EQUAL 32) + set(NVAPI_LIBRARY nvapi) + elseif (WORD_SIZE EQUAL 64) + set(NVAPI_LIBRARY nvapi64) + endif (WORD_SIZE EQUAL 32) + else (WINDOWS) + set(NVAPI_LIBRARY "") + endif (WINDOWS) +else (NVAPI) + set(NVAPI_LIBRARY "") +endif (NVAPI) + diff --git a/indra/cmake/QuickTimePlugin.cmake b/indra/cmake/QuickTimePlugin.cmake index 8afd8f304..cb54e287a 100644 --- a/indra/cmake/QuickTimePlugin.cmake +++ b/indra/cmake/QuickTimePlugin.cmake @@ -8,7 +8,7 @@ endif(INSTALL_PROPRIETARY) if (DARWIN) include(CMakeFindFrameworks) find_library(QUICKTIME_LIBRARY QuickTime) -elseif (WINDOWS) +elseif (WINDOWS AND WORD_SIZE EQUAL 32) set(QUICKTIME_SDK_DIR "$ENV{PROGRAMFILES}/QuickTime SDK" CACHE PATH "Location of the QuickTime SDK.") diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 10dd25ac2..187412b4a 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -37,10 +37,15 @@ set(LIBS_PREBUILT_DIR ${CMAKE_SOURCE_DIR}/../libraries CACHE PATH if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(WINDOWS ON BOOL FORCE) - set(ARCH i686) - set(LL_ARCH ${ARCH}_win32) - set(LL_ARCH_DIR ${ARCH}-win32) - set(WORD_SIZE 32) + if (WORD_SIZE EQUAL 32) + set(ARCH i686) + set(LL_ARCH ${ARCH}_win32) + set(LL_ARCH_DIR ${ARCH}-win32) + elseif (WORD_SIZE EQUAL 64) + set(ARCH x86_64) + set(LL_ARCH ${ARCH}_win) + set(LL_ARCH_DIR ${ARCH}-win) + endif (WORD_SIZE EQUAL 32) endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -92,7 +97,7 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(DARWIN 1) - if(${CMAKE_GENERATOR} MATCHES Xcode) + if(${CMAKE_GENERATOR} MATCHES "Xcode") #SDK Compiler and Deployment targets for XCode if (${XCODE_VERSION} VERSION_LESS 4.0.0) set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk) @@ -101,10 +106,10 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) endif (${XCODE_VERSION} VERSION_LESS 4.0.0) - else(${CMAKE_GENERATOR} MATCHES Xcode) + else(${CMAKE_GENERATOR} MATCHES "Xcode") set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) - endif(${CMAKE_GENERATOR} MATCHES Xcode) + endif(${CMAKE_GENERATOR} MATCHES "Xcode") set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42") @@ -119,15 +124,17 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(LL_ARCH_DIR universal-darwin) endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") -if (WINDOWS) +if (WINDOWS AND WORD_SIZE EQUAL 32) set(PREBUILT_TYPE windows) +elseif (WINDOWS AND WORD_SIZE EQUAL 64) + set(PREBUILT_TYPE windows64) elseif(DARWIN) set(PREBUILT_TYPE darwin) elseif(LINUX AND WORD_SIZE EQUAL 32) set(PREBUILT_TYPE linux) elseif(LINUX AND WORD_SIZE EQUAL 64) set(PREBUILT_TYPE linux64) -endif(WINDOWS) +endif(WINDOWS AND WORD_SIZE EQUAL 32) # Default deploy grid set(GRID agni CACHE STRING "Target Grid") diff --git a/indra/cwdebug/debug.h b/indra/cwdebug/debug.h index 4167813ea..d3c4e686b 100644 --- a/indra/cwdebug/debug.h +++ b/indra/cwdebug/debug.h @@ -144,6 +144,7 @@ extern LL_COMMON_API fake_channel const snapshot; #define CWDEBUG_MARKER 0 #define BACKTRACE do { } while(0) +#define CWD_ONLY(...) #endif // !DOXYGEN @@ -180,6 +181,7 @@ extern LL_COMMON_API fake_channel const snapshot; #include #define CWD_API __attribute__ ((visibility("default"))) +#define CWD_ONLY(...) __VA_ARGS__ //! Debug specific code. namespace debug { diff --git a/indra/develop.py b/indra/develop.py index 853c37e14..4e93c27e9 100755 --- a/indra/develop.py +++ b/indra/develop.py @@ -443,9 +443,15 @@ class WindowsSetup(PlatformSetup): 'vc100' : { 'gen' : r'Visual Studio 10', 'ver' : r'10.0' + }, + 'vc110' : { + 'gen' : r'Visual Studio 11', + 'ver' : r'11.0' } } + gens['vs2010'] = gens['vc100'] + gens['vs2012'] = gens['vc110'] search_path = r'C:\windows' exe_suffixes = ('.exe', '.bat', '.com') @@ -503,6 +509,9 @@ class WindowsSetup(PlatformSetup): project_name=self.project_name, word_size=self.word_size, ) + if self.word_size == 64: + args["generator"] += r' Win64' + #if simple: # return 'cmake %(opts)s "%(dir)s"' % args return ('cmake -G "%(generator)s" ' diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index 11945a239..1522e3e9a 100644 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -192,6 +192,8 @@ def usage(srctree=""): arg['description'] % nd) def main(): + print "cwd:", os.getcwd() + print " ".join(sys.argv) option_names = [arg['name'] + '=' for arg in ARGUMENTS] option_names.append('help') options, remainder = getopt.getopt(sys.argv[1:], "", option_names) @@ -266,7 +268,7 @@ class LLManifest(object): __metaclass__ = LLManifestRegistry manifests = {} def for_platform(self, platform, arch = None): - if arch: + if arch and platform != "windows": platform = platform + '_' + arch return self.manifests[platform.lower()] for_platform = classmethod(for_platform) diff --git a/indra/libhacd/hacdHACD.cpp b/indra/libhacd/hacdHACD.cpp index 35206f8ce..fb2a54e9e 100644 --- a/indra/libhacd/hacdHACD.cpp +++ b/indra/libhacd/hacdHACD.cpp @@ -138,7 +138,7 @@ namespace HACD if (m_callBack) { char msg[1024]; - sprintf(msg, "nCC %lu\n", m_graph.m_nCCs); + sprintf(msg, "nCC %zu\n", m_graph.m_nCCs); (*m_callBack)(msg, 0.0, 0.0, m_graph.GetNVertices()); } @@ -879,7 +879,7 @@ namespace HACD if (m_callBack) { char msg[1024]; - sprintf(msg, "\t CH(%zu) \t %zu \t %lf \t %zu \t %f \t %zu\n", v, static_cast(p), m_graph.m_vertices[v].m_concavity, m_graph.m_vertices[v].m_distPoints.Size(), m_graph.m_vertices[v].m_surf*100.0/m_area, m_graph.m_vertices[v].m_ancestors.size()); + sprintf(msg, "\t CH(%zu) \t %zu \t %lf \t %zu \t %f \t %zu\n", v, p, m_graph.m_vertices[v].m_concavity, m_graph.m_vertices[v].m_distPoints.Size(), m_graph.m_vertices[v].m_surf*100.0/m_area, m_graph.m_vertices[v].m_ancestors.size()); (*m_callBack)(msg, 0.0, 0.0, m_nClusters); p++; } diff --git a/indra/libhacd/hacdHACD.h b/indra/libhacd/hacdHACD.h index 0c9f11653..2ca9a4ae7 100644 --- a/indra/libhacd/hacdHACD.h +++ b/indra/libhacd/hacdHACD.h @@ -22,7 +22,9 @@ #include #include #include - +#if defined(_MSC_VER) && _MSC_VER >= 1700 +#include +#endif namespace HACD { const double sc_pi = 3.14159265; diff --git a/indra/libhacd/hacdRaycastMesh.cpp b/indra/libhacd/hacdRaycastMesh.cpp index 5edd9adc3..2f84bbc11 100644 --- a/indra/libhacd/hacdRaycastMesh.cpp +++ b/indra/libhacd/hacdRaycastMesh.cpp @@ -106,7 +106,7 @@ namespace HACD m_nMaxNodes = 0; for(size_t k = 0; k < maxDepth; k++) { - m_nMaxNodes += (1 << maxDepth); + m_nMaxNodes += (static_cast(1) << maxDepth); } m_nodes = new RMNode[m_nMaxNodes]; RMNode & root = m_nodes[AddNode()]; diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h index 65dd3cdde..47d14d2a1 100644 --- a/indra/llappearance/lldriverparam.h +++ b/indra/llappearance/lldriverparam.h @@ -117,7 +117,8 @@ public: /*virtual*/ void stopAnimating(BOOL upload_bake); /*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params); /*virtual*/ void resetDrivenParams(); - + /*virtual*/ char const* getTypeString(void) const { return "param_driver"; } + // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion(); /*virtual*/ const LLVector4a& getAvgDistortion(); diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h index 03915d3da..f1ecef881 100644 --- a/indra/llappearance/llpolymorph.h +++ b/indra/llappearance/llpolymorph.h @@ -173,6 +173,7 @@ public: // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex sex ); + /*virtual*/ char const* getTypeString(void) const { return "param_morph"; } // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion(); diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h index 774bc7dfa..a9b843af6 100644 --- a/indra/llappearance/llpolyskeletaldistortion.h +++ b/indra/llappearance/llpolyskeletaldistortion.h @@ -109,7 +109,8 @@ public: // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); /*virtual*/ void apply( ESex sex ); - + /*virtual*/ char const* getTypeString(void) const { return "param_skeleton"; } + // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 0.1f; } /*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; } diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h index b38d28d3e..64a465a59 100644 --- a/indra/llappearance/lltexlayerparams.h +++ b/indra/llappearance/lltexlayerparams.h @@ -86,6 +86,7 @@ public: /*virtual*/ void setWeight(F32 weight, BOOL upload_bake); /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake); /*virtual*/ void animate(F32 delta, BOOL upload_bake); + /*virtual*/ char const* getTypeString(void) const { return "param_alpha"; } // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 1.f; } @@ -177,7 +178,7 @@ public: /*virtual*/ void setWeight(F32 weight, BOOL upload_bake); /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake); /*virtual*/ void animate(F32 delta, BOOL upload_bake); - + /*virtual*/ char const* getTypeString(void) const { return "param_color"; } // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 1.f; } diff --git a/indra/llappearance/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp index dd5331207..4a4f69c56 100644 --- a/indra/llappearance/llviewervisualparam.cpp +++ b/indra/llappearance/llviewervisualparam.cpp @@ -143,6 +143,12 @@ BOOL LLViewerVisualParam::setInfo(LLViewerVisualParamInfo *info) return TRUE; } +//virtual +std::string LLViewerVisualParam::getDumpWearableTypeName(void) const +{ + return LLWearableType::getTypeName(LLWearableType::EType(getInfo()->mWearableType)); +} + /* //============================================================================= // These virtual functions should always be overridden, diff --git a/indra/llappearance/llviewervisualparam.h b/indra/llappearance/llviewervisualparam.h index 64364c881..39d29fccb 100644 --- a/indra/llappearance/llviewervisualparam.h +++ b/indra/llappearance/llviewervisualparam.h @@ -82,6 +82,7 @@ public: // LLVisualParam Virtual functions ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); + /*virtual*/ std::string getDumpWearableTypeName(void) const; // New Virtual functions virtual F32 getTotalDistortion() = 0; diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index b6049eb21..a944a16fd 100644 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -41,6 +41,7 @@ class LLVisualParam; class LLTexGlobalColorInfo; class LLTexGlobalColor; class LLAvatarAppearance; +class AIArchetype; // Abstract class. class LLWearable diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 300264d91..972725171 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -59,8 +59,13 @@ bool attemptDelayLoad() { __try { +#if defined(_WIN64) + if( FAILED( __HrLoadAllImportsForDll( "fmodex64.dll" ) ) ) + return false; +#else if( FAILED( __HrLoadAllImportsForDll( "fmodex.dll" ) ) ) return false; +#endif } __except( EXCEPTION_EXECUTE_HANDLER ) { diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index a5864c15c..6cb1fcaa6 100644 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -162,6 +162,10 @@ public: void setParamLocation(EParamLocation loc); EParamLocation getParamLocation() const { return mParamLocation; } + // Singu extensions. Used for dumping the archtype. + virtual char const* getTypeString(void) const = 0; + virtual std::string getDumpWearableTypeName(void) const = 0; + protected: F32 mCurWeight; // current weight F32 mLastWeight; // last weight diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 2b4c37be0..be045f100 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -17,6 +17,8 @@ include_directories( ) set(llcommon_SOURCE_FILES + aialert.cpp + aifile.cpp aiframetimer.cpp aithreadid.cpp imageids.cpp @@ -106,6 +108,8 @@ set(llcommon_SOURCE_FILES set(llcommon_HEADER_FILES CMakeLists.txt + aialert.h + aifile.h aiframetimer.h airecursive.h aithreadid.h diff --git a/indra/llcommon/aialert.cpp b/indra/llcommon/aialert.cpp new file mode 100644 index 000000000..587a206bc --- /dev/null +++ b/indra/llcommon/aialert.cpp @@ -0,0 +1,82 @@ +/** + * @file aialert.cpp + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 02/11/2013 + * - Initial version, written by Aleric Inglewood @ SL + * + * 05/11/2013 + * Moved everything in namespace AIAlert, except AIArgs. + */ + +#include "aialert.h" + +namespace AIAlert +{ + +Error::Error(Prefix const& prefix, modal_nt type, + Error const& alert) : mLines(alert.mLines), mModal(type) +{ + if (alert.mModal == modal) mModal = modal; + if (prefix) mLines.push_front(Line(prefix)); +} + +Error::Error(Prefix const& prefix, modal_nt type, + std::string const& xml_desc, AIArgs const& args) : mModal(type) +{ + if (prefix) mLines.push_back(Line(prefix)); + mLines.push_back(Line(xml_desc, args)); +} + +Error::Error(Prefix const& prefix, modal_nt type, + Error const& alert, + std::string const& xml_desc, AIArgs const& args) : mLines(alert.mLines), mModal(type) +{ + if (alert.mModal == modal) mModal = modal; + if (prefix) mLines.push_back(Line(prefix, !mLines.empty())); + mLines.push_back(Line(xml_desc, args)); +} + +Error::Error(Prefix const& prefix, modal_nt type, + std::string const& xml_desc, + Error const& alert) : mLines(alert.mLines), mModal(type) +{ + if (alert.mModal == modal) mModal = modal; + if (!mLines.empty()) { mLines.front().set_newline(); } + mLines.push_front(Line(xml_desc)); + if (prefix) mLines.push_front(Line(prefix)); +} + +Error::Error(Prefix const& prefix, modal_nt type, + std::string const& xml_desc, AIArgs const& args, + Error const& alert) : mLines(alert.mLines), mModal(type) +{ + if (alert.mModal == modal) mModal = modal; + if (!mLines.empty()) { mLines.front().set_newline(); } + mLines.push_front(Line(xml_desc, args)); + if (prefix) mLines.push_front(Line(prefix)); +} + +} // namespace AIAlert + diff --git a/indra/llcommon/aialert.h b/indra/llcommon/aialert.h new file mode 100644 index 000000000..4d3704cfb --- /dev/null +++ b/indra/llcommon/aialert.h @@ -0,0 +1,306 @@ +/** + * @file aialert.h + * @brief Declaration of AIArgs and AIAlert classes. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 02/11/2013 + * Initial version, written by Aleric Inglewood @ SL + * + * 05/11/2013 + * Moved everything in namespace AIAlert, except AIArgs. + */ + +#ifndef AI_ALERT +#define AI_ALERT + +#include "llpreprocessor.h" +#include "llstring.h" +#include +#include + +//=================================================================================================================================== +// Facility to throw errors that can easily be converted to an informative pop-up floater for the user. + +// Throw arbitrary class. +#define THROW_ALERT_CLASS(Alert, ...) throw Alert(AIAlert::Prefix(), AIAlert::not_modal, __VA_ARGS__) +#define THROW_MALERT_CLASS(Alert, ...) throw Alert(AIAlert::Prefix(), AIAlert::modal, __VA_ARGS__) +#ifdef __GNUC__ +#define THROW_FALERT_CLASS(Alert, ...) throw Alert(AIAlert::Prefix(__PRETTY_FUNCTION__, AIAlert::pretty_function_prefix), AIAlert::not_modal, __VA_ARGS__) +#define THROW_FMALERT_CLASS(Alert, ...) throw Alert(AIAlert::Prefix(__PRETTY_FUNCTION__, AIAlert::pretty_function_prefix), AIAlert::modal, __VA_ARGS__) +#else +#define THROW_FALERT_CLASS(Alert, ...) throw Alert(AIAlert::Prefix(__FUNCTION__, AIAlert::pretty_function_prefix), AIAlert::not_modal, __VA_ARGS__) +#define THROW_FMALERT_CLASS(Alert, ...) throw Alert(AIAlert::Prefix(__FUNCTION__, AIAlert::pretty_function_prefix), AIAlert::modal, __VA_ARGS__) +#endif + +// Shortcut to throw AIAlert::Error. +#define THROW_ALERT(...) THROW_ALERT_CLASS(AIAlert::Error, __VA_ARGS__) +#define THROW_MALERT(...) THROW_MALERT_CLASS(AIAlert::Error, __VA_ARGS__) +#define THROW_FALERT(...) THROW_FALERT_CLASS(AIAlert::Error, __VA_ARGS__) +#define THROW_FMALERT(...) THROW_FMALERT_CLASS(AIAlert::Error, __VA_ARGS__) + +// Shortcut to throw AIAlert::ErrorCode. +#define THROW_ALERTC(...) THROW_ALERT_CLASS(AIAlert::ErrorCode, __VA_ARGS__) +#define THROW_MALERTC(...) THROW_MALERT_CLASS(AIAlert::ErrorCode, __VA_ARGS__) +#define THROW_FALERTC(...) THROW_FALERT_CLASS(AIAlert::ErrorCode, __VA_ARGS__) +#define THROW_FMALERTC(...) THROW_FMALERT_CLASS(AIAlert::ErrorCode, __VA_ARGS__) + +// Shortcut to throw AIAlert::ErrorCode with errno as code. +#define THROW_ALERTE(...) do { int errn = errno; THROW_ALERT_CLASS(AIAlert::ErrorCode, errn, __VA_ARGS__); } while(0) +#define THROW_MALERTE(...) do { int errn = errno; THROW_MALERT_CLASS(AIAlert::ErrorCode, errn, __VA_ARGS__); } while(0) +#define THROW_FALERTE(...) do { int errn = errno; THROW_FALERT_CLASS(AIAlert::ErrorCode, errn, __VA_ARGS__); } while(0) +#define THROW_FMALERTE(...) do { int errn = errno; THROW_FMALERT_CLASS(AIAlert::ErrorCode, errn, __VA_ARGS__); } while(0) + +// Examples + +#ifdef EXAMPLE_CODE + + //---------------------------------------------------------- + // To show the alert box: + + catch (AIAlert::Error const& error) + { + AIAlert::add(error); // Optionally pass pretty_function_prefix as second parameter to *suppress* that output. + } + + // or, for example + + catch (AIAlert::ErrorCode const& error) + { + if (error.getCode() != EEXIST) + { + AIAlert::add(alert, AIAlert::pretty_function_prefix); + } + } + //---------------------------------------------------------- + // To throw alerts: + + THROW_ALERT("ExampleKey"); // A) Lookup "ExampleKey" in strings.xml and show translation. + THROW_ALERT("ExampleKey", AIArgs("[FIRST]", first)("[SECOND]", second)(...etc...)); // B) Same as A, but replace [FIRST] with first, [SECOND] with second, etc. + THROW_ALERT("ExampleKey", error); // C) As A, but followed by a colon and a newline, and then the text of 'error'. + THROW_ALERT(error, "ExampleKey"); // D) The text of 'error', followed by a colon and a newline and then as A. + THROW_ALERT("ExampleKey", AIArgs("[FIRST]", first)("[SECOND]", second), error); // E) As B, but followed by a colon and a newline, and then the text of 'error'. + THROW_ALERT(error, "ExampleKey", AIArgs("[FIRST]", first)("[SECOND]", second)); // F) The text of 'error', followed by a colon and a newline and then as B. + // where 'error' is a caught Error object (as above) in a rethrow. + // Prepend ALERT with M and/or F to make the alert box Modal and/or prepend the text with the current function name. + // For example, + THROW_MFALERT("ExampleKey", AIArgs("[FIRST]", first)); // Throw a Modal alert box that is prefixed with the current Function name. + // Append E after ALERT to throw an ErrorCode class that contains the current errno. + // For example, + THROW_FALERTE("ExampleKey", AIArgs("[FIRST]", first)); // Throw an alert box that is prefixed with the current Function name and pass errno to the catcher. + +#endif // EXAMPLE_CODE + +// +//=================================================================================================================================== + +// A wrapper around LLStringUtil::format_map_t to allow constructing a dictionary +// on one line by doing: +// +// AIArgs("[ARG1]", arg1)("[ARG2]", arg2)("[ARG3]", arg3)... + +class LL_COMMON_API AIArgs +{ + private: + LLStringUtil::format_map_t mArgs; // The underlying replacement map. + + public: + // Construct an empty map. + AIArgs(void) { } + // Construct a map with a single replacement. + AIArgs(char const* key, std::string const& replacement) { mArgs[key] = replacement; } + // Add another replacement. + AIArgs& operator()(char const* key, std::string const& replacement) { mArgs[key] = replacement; return *this; } + // The destructor may not throw. + ~AIArgs() throw() { } + + // Accessor. + LLStringUtil::format_map_t const& operator*() const { return mArgs; } +}; + +namespace AIAlert +{ + +enum modal_nt +{ + not_modal, + modal +}; + +enum alert_line_type_nt +{ + normal = 0, + empty_prefix = 1, + pretty_function_prefix = 2 + // These must exist of single bits (a mask). +}; + +// An Prefix currently comes only in two flavors: +// +// empty_prefix : An empty prefix. +// pretty_function_prefix : A function name prefix, this is the function from which the alert was thrown. + +class LL_COMMON_API Prefix +{ + public: + Prefix(void) : mType(empty_prefix) { } + Prefix(char const* str, alert_line_type_nt type) : mStr(str), mType(type) { } + + operator bool(void) const { return mType != empty_prefix; } + alert_line_type_nt type(void) const { return mType; } + std::string const& str(void) const { return mStr; } + + private: + std::string mStr; // Literal text. For example a C++ function name. + alert_line_type_nt mType; // The type of this prefix. +}; + +// A class that represents one line with its replacements. +// The string mXmlDesc shall be looked up in strings.xml. +// This is not done as part of this class because LLTrans::getString +// is not part of llcommon. + +class LL_COMMON_API Line +{ + private: + bool mNewline; // Prepend this line with a newline if set. + std::string mXmlDesc; // The keyword to look up in string.xml. + AIArgs mArgs; // Replacement map. + alert_line_type_nt mType; // The type of this line: normal for normal lines, other for prefixes. + + public: + Line(std::string const& xml_desc, bool newline = false) : mNewline(newline), mXmlDesc(xml_desc), mType(normal) { } + Line(std::string const& xml_desc, AIArgs const& args, bool newline = false) : mNewline(newline), mXmlDesc(xml_desc), mArgs(args), mType(normal) { } + Line(Prefix const& prefix, bool newline = false) : mNewline(newline), mXmlDesc("AIPrefix"), mArgs("[PREFIX]", prefix.str()), mType(prefix.type()) { } + // The destructor may not throw. + ~Line() throw() { } + + // Prepend a newline before this line. + void set_newline(void) { mNewline = true; } + + // These are to be used like: LLTrans::getString(line.getXmlDesc(), line.args()) and prepend with a \n if prepend_newline() returns true. + std::string getXmlDesc(void) const { return mXmlDesc; } + LLStringUtil::format_map_t const& args(void) const { return *mArgs; } + bool prepend_newline(void) const { return mNewline; } + + // Accessors. + bool suppressed(unsigned int suppress_mask) const { return (suppress_mask & mType) != 0; } + bool is_prefix(void) const { return mType != normal; } +}; + +// This class is used to throw an error that will cause +// an alert box to pop up for the user. +// +// An alert box only has text and an OK button. +// The alert box does not give feed back to the program; it is purely informational. + +// The class represents multiple lines, each line is to be translated and catenated, +// separated by newlines, and then written to an alert box. This is not done as part +// of this class because LLTrans::getString and LLNotification is not part of llcommon. +// Instead call LLNotificationUtil::add(Error const&). + +class LL_COMMON_API Error : public std::exception +{ + public: + typedef std::deque lines_type; + + // The destructor may not throw. + ~Error() throw() { } + + // Accessors. + lines_type const& lines(void) const { return mLines; } + bool is_modal(void) const { return mModal == modal; } + + // Existing alert, just add a prefix and turn alert into modal if appropriate. + Error(Prefix const& prefix, modal_nt type, Error const& alert); + + // A string with zero or more replacements. + Error(Prefix const& prefix, modal_nt type, + std::string const& xml_desc, AIArgs const& args = AIArgs()); + + // Same as above bit prepending the message with the text of another alert. + Error(Prefix const& prefix, modal_nt type, + Error const& alert, + std::string const& xml_desc, AIArgs const& args = AIArgs()); + + // Same as above but appending the message with the text of another alert. + // (no args) + Error(Prefix const& prefix, modal_nt type, + std::string const& xml_desc, + Error const& alert); + // (with args) + Error(Prefix const& prefix, modal_nt type, + std::string const& xml_desc, AIArgs const& args, + Error const& alert); + + private: + lines_type mLines; // The lines (or prefixes) of text to be displayed, each consisting on a keyword (to be looked up in strings.xml) and a replacement map. + modal_nt mModal; // If true, make the alert box a modal floater. +}; + +// Same as Error but allows to pass an additional error code. + +class LL_COMMON_API ErrorCode : public Error +{ + private: + int mCode; + + public: + // The destructor may not throw. + ~ErrorCode() throw() { } + + // Accessor. + int getCode(void) const { return mCode; } + + // Just an Error with a code. + ErrorCode(Prefix const& prefix, modal_nt type, int code, + Error const& alert) : + Error(prefix, type, alert), mCode(code) { } + + // A string with zero or more replacements. + ErrorCode(Prefix const& prefix, modal_nt type, int code, + std::string const& xml_desc, AIArgs const& args = AIArgs()) : + Error(prefix, type, xml_desc, args), mCode(code) { } + + // Same as above bit prepending the message with the text of another alert. + ErrorCode(Prefix const& prefix, modal_nt type, int code, + Error const& alert, + std::string const& xml_desc, AIArgs const& args = AIArgs()) : + Error(prefix, type, alert, xml_desc, args), mCode(code) { } + + // Same as above but appending the message with the text of another alert. + // (no args) + ErrorCode(Prefix const& prefix, modal_nt type, int code, + std::string const& xml_desc, + Error const& alert) : + Error(prefix, type, xml_desc, alert), mCode(code) { } + // (with args) + ErrorCode(Prefix const& prefix, modal_nt type, int code, + std::string const& xml_desc, AIArgs const& args, + Error const& alert) : + Error(prefix, type, xml_desc, args, alert), mCode(code) { } +}; + +} // namespace AIAlert + +#endif // AI_ALERT diff --git a/indra/llcommon/aifile.cpp b/indra/llcommon/aifile.cpp new file mode 100644 index 000000000..cd2ade77a --- /dev/null +++ b/indra/llcommon/aifile.cpp @@ -0,0 +1,119 @@ +/** + * @file aifile.cpp + * @brief POSIX file operations that throw on error. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 03/11/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#include "linden_common.h" +#include "aifile.h" +#include "aialert.h" + +#if LL_WINDOWS +#include +#include // Windows errno +#else +#include +#endif + +AIFile::AIFile(std::string const& filename, char const* accessmode) +{ + mFp = AIFile::fopen(filename, accessmode); +} + +AIFile::~AIFile() +{ + AIFile::close(mFp); +} + +// Like THROW_MALERTE but appends "LLFile::strerr(errn) << " (" << errn << ')'" as argument to replace [ERROR]. +#define THROW_ERROR(...) \ + do { \ + int errn = errno; \ + std::ostringstream error; \ + error << LLFile::strerr(errn) << " (" << errn << ')'; \ + THROW_MALERT_CLASS(AIAlert::ErrorCode, errn, __VA_ARGS__ ("[ERROR]", error.str())); \ + } while(0) + +//static +void AIFile::mkdir(std::string const& dirname, int perms) +{ + int rc = LLFile::mkdir_nowarn(dirname, perms); + if (rc < 0 && errno != EEXIST) + { + THROW_ERROR("AIFile_mkdir_Failed_to_create_DIRNAME", AIArgs("[DIRNAME]", dirname)); + } +} + +//static +void AIFile::rmdir(std::string const& dirname) +{ + int rc = LLFile::rmdir_nowarn(dirname); + if (rc < 0 && errno != ENOENT) + { + THROW_ERROR("AIFile_rmdir_Failed_to_remove_DIRNAME", AIArgs("[DIRNAME]", dirname)); + } +} + +//static +LLFILE* AIFile::fopen(std::string const& filename, const char* mode) +{ + LLFILE* fp = LLFile::fopen(filename, mode); + if (!fp) + { + THROW_ERROR("AIFile_fopen_Failed_to_open_FILENAME", AIArgs("[FILENAME]", filename)); + } + return fp; +} + +//static +void AIFile::close(LLFILE* file) +{ + if (LLFile::close(file) < 0) + { + THROW_ERROR("AIFile_close_Failed_to_close_file", AIArgs); + } +} + +//static +void AIFile::remove(std::string const& filename) +{ + int rc = LLFile::remove_nowarn(filename); + if (rc < 0 && errno != ENOENT) + { + THROW_ERROR("AIFile_remove_Failed_to_remove_FILENAME", AIArgs("[FILENAME]", filename)); + } +} + +//static +void AIFile::rename(std::string const& filename, std::string const& newname) +{ + if (LLFile::rename_nowarn(filename, newname) < 0) + { + THROW_ERROR("AIFile_rename_Failed_to_rename_FILE_to_NEWFILE", AIArgs("[FILE]", filename)("[NEWFILE]", newname)); + } +} + diff --git a/indra/llcommon/aifile.h b/indra/llcommon/aifile.h new file mode 100644 index 000000000..1b110496a --- /dev/null +++ b/indra/llcommon/aifile.h @@ -0,0 +1,59 @@ +/** + * @file aifile.h + * @brief Declaration of AIFile. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 02/11/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AIFILE_H +#define AIFILE_H + +#include "llfile.h" + +// As LLFile, but throws AIAlert instead of printing a warning. +class LL_COMMON_API AIFile +{ + private: + LLFILE* mFp; + + public: + // Scoped file (exception safe). Throws AIAlertCode with errno on failure. + AIFile(std::string const& filename, char const* accessmode); + ~AIFile(); + + operator LLFILE* () const { return mFp; } + + // All these functions take UTF8 path/filenames. + static LLFILE* fopen(std::string const& filename, char const* accessmode); + static void close(LLFILE* file); + + static void mkdir(std::string const& dirname, int perms = 0700); // Does NOT throw when dirname already exists. + static void rmdir(std::string const& dirname); // Does NOT throw when dirname does not exist. + static void remove(std::string const& filename); // Does NOT throw when filename does not exist. + static void rename(std::string const& filename, std::string const& newname); +}; + +#endif // AIFILE_H diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 2026a9e4d..40ae4a0a8 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -123,6 +123,8 @@ LLApp::LLApp() : mThreadErrorp(NULL) commonCtor(); } +static void* sCrashLoggerReserve = NULL; + void LLApp::commonCtor() { // Set our status to running @@ -148,6 +150,12 @@ void LLApp::commonCtor() sApplication = this; mExceptionHandler = 0; + +#if LL_WINDOWS + sCrashLoggerReserve = VirtualAlloc(NULL, 512*1024, MEM_COMMIT|MEM_RESERVE, PAGE_NOACCESS); +#else + sCrashLoggerReserve = malloc(512*1024); +#endif // initialize the buffer to write the minidump filename to // (this is used to avoid allocating memory in the crash handler) @@ -155,6 +163,20 @@ void LLApp::commonCtor() mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe"; } +#if LL_WINDOWS +static bool clear_CrashLoggerReserve_callback(void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion) +{ + VirtualFree(sCrashLoggerReserve, 0, MEM_RELEASE); + return true; +} +#else +static bool clear_CrashLoggerReserve_callback(void* context) +{ + free(sCrashLoggerReserve); + return true; +} +#endif + LLApp::LLApp(LLErrorThread *error_thread) : mThreadErrorp(error_thread) { @@ -307,46 +329,12 @@ void LLApp::setupErrorHandling() // Install the Google Breakpad crash handler for Windows if(mExceptionHandler == 0) { - llwarns << "adding breakpad exception handler" << llendl; - - std::wostringstream ws; - ws << mCrashReportPipeStr << getPid(); - std::wstring wpipe_name = ws.str(); - std::string ptmp = std::string(wpipe_name.begin(), wpipe_name.end()); - - ::Sleep(2000); //HACK hopefully a static wait won't blow up in my face before google fixes their implementation. - - //HACK this for loop is ueless. Breakpad dumbly returns success when the OOP handler isn't initialized. - for (int retries=0;retries<5;++retries) - { - mExceptionHandler = new google_breakpad::ExceptionHandler( - L"", - NULL, //No filter - windows_post_minidump_callback, - 0, - google_breakpad::ExceptionHandler::HANDLER_ALL, - MiniDumpNormal, //Generate a 'normal' minidump. - (WCHAR *)wpipe_name.c_str(), - NULL); //No custom client info. - if (mExceptionHandler) - { - break; - } - else - { - ::Sleep(100); //Wait a tick and try again. - } - } - if (!mExceptionHandler) - { - llwarns << "Failed to initialize OOP exception handler. Defaulting to In Process handling" << llendl; - mExceptionHandler = new google_breakpad::ExceptionHandler( - std::wstring(mDumpPath.begin(),mDumpPath.end()), //Dump path - 0, //dump filename - windows_post_minidump_callback, - 0, - google_breakpad::ExceptionHandler::HANDLER_ALL); - } + mExceptionHandler = new google_breakpad::ExceptionHandler( + std::wstring(mDumpPath.begin(),mDumpPath.end()), //Dump path + clear_CrashLoggerReserve_callback, + windows_post_minidump_callback, + 0, + google_breakpad::ExceptionHandler::HANDLER_ALL); if (mExceptionHandler) { mExceptionHandler->set_handle_debug_exceptions(true); @@ -401,7 +389,7 @@ void LLApp::setupErrorHandling() if(installHandler && (mExceptionHandler == 0)) { - mExceptionHandler = new google_breakpad::ExceptionHandler(mDumpPath, 0, &unix_post_minidump_callback, 0, true, 0); + mExceptionHandler = new google_breakpad::ExceptionHandler(mDumpPath, clear_CrashLoggerReserve_callback, &unix_post_minidump_callback, 0, true, 0); } #elif LL_LINUX if(installHandler && (mExceptionHandler == 0)) @@ -411,8 +399,7 @@ void LLApp::setupErrorHandling() mDumpPath = "/tmp"; } google_breakpad::MinidumpDescriptor desc(mDumpPath); - //mExceptionHandler = new google_breakpad::ExceptionHandler(desc, 0, unix_minidump_callback, 0, true, 0); - mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1); + mExceptionHandler = new google_breakpad::ExceptionHandler(desc, clear_CrashLoggerReserve_callback, unix_minidump_callback, NULL, true, -1); } #endif diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index 07ea31a5a..e753fe309 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -184,7 +184,7 @@ LLMutex* LLFastTimer::sLogLock = NULL; std::queue LLFastTimer::sLogQueue; const int LLFastTimer::NamedTimer::HISTORY_NUM = 300; -#if LL_WINDOWS +#if defined(LL_WINDOWS) && !defined(_WIN64) #define USE_RDTSC 1 #endif diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index e0e9d3a27..686a516b9 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -49,7 +49,8 @@ static std::string empty; #if LL_WINDOWS // On Windows, use strerror_s(). -std::string strerr(int errn) +//static +std::string LLFile::strerr(int errn) { char buffer[256]; strerror_s(buffer, errn); // infers sizeof(buffer) -- love it! @@ -98,7 +99,8 @@ std::string message_from(int orig_errno, const char* buffer, size_t bufflen, << " (error " << stre_errno << ')'); } -std::string strerr(int errn) +//static +std::string LLFile::strerr(int errn) { char buffer[256]; // Select message_from() function matching the strerror_r() we have on hand. @@ -108,7 +110,8 @@ std::string strerr(int errn) #endif // ! LL_WINDOWS // On either system, shorthand call just infers global 'errno'. -std::string strerr() +//static +std::string LLFile::strerr() { return strerr(errno); } @@ -125,7 +128,7 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc if (errn != accept) { LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename - << "' (errno " << errn << "): " << strerr(errn) << LL_ENDL; + << "' (errno " << errn << "): " << LLFile::strerr(errn) << LL_ENDL; } #if 0 && LL_WINDOWS // turn on to debug file-locking problems // If the problem is "Permission denied," maybe it's because another @@ -171,7 +174,7 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc } // static -int LLFile::mkdir(const std::string& dirname, int perms) +int LLFile::mkdir_nowarn(const std::string& dirname, int perms) { #if LL_WINDOWS // permissions are ignored on Windows @@ -181,13 +184,19 @@ int LLFile::mkdir(const std::string& dirname, int perms) #else int rc = ::mkdir(dirname.c_str(), (mode_t)perms); #endif + return rc; +} + +int LLFile::mkdir(const std::string& dirname, int perms) +{ + int rc = LLFile::mkdir_nowarn(dirname, perms); // We often use mkdir() to ensure the existence of a directory that might // already exist. Don't spam the log if it does. return warnif("mkdir", dirname, rc, EEXIST); } // static -int LLFile::rmdir(const std::string& dirname) +int LLFile::rmdir_nowarn(const std::string& dirname) { #if LL_WINDOWS // permissions are ignored on Windows @@ -197,6 +206,12 @@ int LLFile::rmdir(const std::string& dirname) #else int rc = ::rmdir(dirname.c_str()); #endif + return rc; +} + +int LLFile::rmdir(const std::string& dirname) +{ + int rc = LLFile::rmdir_nowarn(dirname); return warnif("rmdir", dirname, rc); } @@ -238,8 +253,7 @@ int LLFile::close(LLFILE * file) return ret_value; } - -int LLFile::remove(const std::string& filename) +int LLFile::remove_nowarn(const std::string& filename) { #if LL_WINDOWS std::string utf8filename = filename; @@ -248,10 +262,16 @@ int LLFile::remove(const std::string& filename) #else int rc = ::remove(filename.c_str()); #endif + return rc; +} + +int LLFile::remove(const std::string& filename) +{ + int rc = LLFile::remove_nowarn(filename); return warnif("remove", filename, rc); } -int LLFile::rename(const std::string& filename, const std::string& newname) +int LLFile::rename_nowarn(const std::string& filename, const std::string& newname) { #if LL_WINDOWS std::string utf8filename = filename; @@ -262,6 +282,12 @@ int LLFile::rename(const std::string& filename, const std::string& newname) #else int rc = ::rename(filename.c_str(),newname.c_str()); #endif + return rc; +} + +int LLFile::rename(const std::string& filename, const std::string& newname) +{ + int rc = LLFile::rename_nowarn(filename, newname); return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc); } diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 12eb04932..cc990f6ab 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -30,6 +30,9 @@ #ifndef LL_LLFILE_H #define LL_LLFILE_H +#include +#include + /** * This class provides a cross platform interface to the filesystem. * Attempts to mostly mirror the POSIX style IO functions. @@ -37,9 +40,6 @@ typedef FILE LLFILE; -#include -#include - #if LL_WINDOWS // windows version of stat function and stat data structure are called _stat typedef struct _stat llstat; @@ -68,6 +68,12 @@ public: static int close(LLFILE * file); + // Singu extension: the same as below, but doesn't print a warning as to leave errno alone. + static int mkdir_nowarn(const std::string& filename, int perms); + static int rmdir_nowarn(const std::string& filename); + static int remove_nowarn(const std::string& filename); + static int rename_nowarn(const std::string& filename, const std::string& newname); + // perms is a permissions mask like 0777 or 0700. In most cases it will // be overridden by the user's umask. It is ignored on Windows. static int mkdir(const std::string& filename, int perms = 0700); @@ -82,6 +88,9 @@ public: std::ios::openmode mode); static const char * tmpdir(); + + static std::string strerr(int errn); + static std::string strerr(); }; /** diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 3c096abe1..729f066fb 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -32,6 +32,7 @@ #include #include "string_table.h" +#include "llerror.h" // llassert_always #include #include #include diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index 1409c55d1..46775313d 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -281,7 +281,12 @@ void LLMD5::raw_digest(unsigned char *s) const return; } - +//Singu extension: the inverse of LLMD5::raw_digest. +void LLMD5::clone(unsigned char const* s) +{ + memcpy(digest, s, 16); + finalized = 1; +} void LLMD5::hex_digest(char *s) const { @@ -305,12 +310,26 @@ void LLMD5::hex_digest(char *s) const return; } +//Singu extension: the inverse of LLMD5::hex_digest. +void LLMD5::clone(std::string const& hash_str) +{ + for (int i = 0; i < 16; ++i) + { + unsigned char byte = 0; + for (int j = 0; j < 2; ++j) + { + char c = hash_str[i * 2 + j]; + unsigned char nibble = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10; + byte += nibble << ((1 - j) << 2); + } + digest[i] = byte; + } + finalized = 1; +} - - -std::ostream& operator<<(std::ostream &stream, LLMD5 context) +std::ostream& operator<<(std::ostream &stream, LLMD5 const& context) { char s[33]; /* Flawfinder: ignore */ context.hex_digest(s); @@ -318,23 +337,6 @@ std::ostream& operator<<(std::ostream &stream, LLMD5 context) return stream; } -bool operator==(const LLMD5& a, const LLMD5& b) -{ - unsigned char a_guts[16]; - unsigned char b_guts[16]; - a.raw_digest(a_guts); - b.raw_digest(b_guts); - if (memcmp(a_guts,b_guts,16)==0) - return true; - else - return false; -} - -bool operator!=(const LLMD5& a, const LLMD5& b) -{ - return !(a==b); -} - // PRIVATE METHODS: void LLMD5::init(){ diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index 8bf715f14..8909f04d4 100644 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h @@ -32,6 +32,10 @@ #ifndef LL_LLMD5_H #define LL_LLMD5_H +#include "llpreprocessor.h" +#include +#include // memcmp + // LLMD5.CC - source code for the C++/object oriented translation and // modification of MD5. @@ -98,18 +102,27 @@ public: void update (const std::string& str); void finalize (); + bool isFinalized() const { return finalized; } + // constructors for special circumstances. All these constructors finalize // the MD5 context. LLMD5 (const unsigned char *string); // digest string, finalize LLMD5 (std::istream& stream); // digest stream, finalize LLMD5 (FILE *file); // digest file, close, finalize LLMD5 (const unsigned char *string, const unsigned int number); + + // Singu extension: set digest directly, finalize. + void clone(unsigned char const* digest); // Inverse of raw_digest. + void clone(std::string const& hash_str); // Inverse of hex_digest. // methods to acquire finalized result void raw_digest(unsigned char *array) const; // provide 16-byte array for binary data void hex_digest(char *string) const; // provide 33-byte array for ascii-hex string - friend LL_COMMON_API std::ostream& operator<< (std::ostream&, LLMD5 context); + friend LL_COMMON_API std::ostream& operator<< (std::ostream&, LLMD5 const& context); + friend LL_COMMON_API bool operator==(const LLMD5& a, const LLMD5& b) { return std::memcmp(a.digest ,b.digest, 16) == 0; } + friend LL_COMMON_API bool operator!=(const LLMD5& a, const LLMD5& b) { return std::memcmp(a.digest ,b.digest, 16) != 0; } + friend LL_COMMON_API bool operator<(const LLMD5& a, const LLMD5& b) { return std::memcmp(a.digest ,b.digest, 16) < 0; } private: @@ -131,7 +144,4 @@ private: }; -LL_COMMON_API bool operator==(const LLMD5& a, const LLMD5& b); -LL_COMMON_API bool operator!=(const LLMD5& a, const LLMD5& b); - #endif // LL_LLMD5_H diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 084f9780c..50739b677 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -200,7 +200,7 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __ assert((bytes % sizeof(F32))== 0); ll_assert_aligned(src,16); ll_assert_aligned(dst,16); - assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src)); + assert((src < dst) ? ((src + bytes) <= dst) : ((dst + bytes) <= src)); assert(bytes%16==0); char* end = dst + bytes; diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index ce2c593c5..a7d2eac67 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -416,7 +416,7 @@ static F64 calculate_cpu_frequency(U32 measure_msecs) unsigned long dwCurPriorityClass = GetPriorityClass(hProcess); int iCurThreadPriority = GetThreadPriority(hThread); unsigned long dwProcessMask, dwSystemMask, dwNewMask = 1; - GetProcessAffinityMask(hProcess, &dwProcessMask, &dwSystemMask); + GetProcessAffinityMask(hProcess, (PDWORD_PTR)&dwProcessMask, (PDWORD_PTR)&dwSystemMask); SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS); SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL); diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index b7831e7fa..4df84028a 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -27,6 +27,9 @@ #define LLREFCOUNT_H #include +#include "llpreprocessor.h" // LL_COMMON_API +#include "stdtypes.h" // S32 +#include "llerror.h" // llassert #define LL_REF_COUNT_DEBUG 0 #if LL_REF_COUNT_DEBUG diff --git a/indra/llcommon/llrun.h b/indra/llcommon/llrun.h index 1fc9925df..1701800b1 100644 --- a/indra/llcommon/llrun.h +++ b/indra/llcommon/llrun.h @@ -37,6 +37,8 @@ #include #include +#include "llpreprocessor.h" +#include "stdtypes.h" class LLRunnable; diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 78b8f95be..a780a6a24 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -27,6 +27,7 @@ #include "llerror.h" // *TODO: eliminate this +#include #include #include diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 35d20d2ee..112a25e66 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -231,7 +231,9 @@ public: operator std::string() const { return mString; } bool operator<(const LLFormatMapString& rhs) const { return mString < rhs.mString; } std::size_t length() const { return mString.length(); } - + // The destructor may not throw. + ~LLFormatMapString() throw() { } + private: std::string mString; }; diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index e7b1f525e..ef99c13e7 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -28,6 +28,7 @@ #include #include +#include #include "stdtypes.h" #include "llpreprocessor.h" diff --git a/indra/llcommon/llversionviewer.h.in b/indra/llcommon/llversionviewer.h.in index f97e2acd0..9252cf4cd 100644 --- a/indra/llcommon/llversionviewer.h.in +++ b/indra/llcommon/llversionviewer.h.in @@ -35,7 +35,7 @@ const S32 LL_VERSION_MAJOR = 1; const S32 LL_VERSION_MINOR = 8; -const S32 LL_VERSION_PATCH = 3; +const S32 LL_VERSION_PATCH = 4; const S32 LL_VERSION_BUILD = ${vBUILD}; const char * const LL_CHANNEL = "${VIEWER_CHANNEL}"; diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 6d3f06710..274663643 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -140,7 +140,7 @@ inline F64 llabs(const F64 a) inline S32 lltrunc( F32 f ) { -#if LL_WINDOWS && !defined( __INTEL_COMPILER ) +#if LL_WINDOWS && !defined( __INTEL_COMPILER ) && !defined(_WIN64) // Avoids changing the floating point control word. // Add or subtract 0.5 - epsilon and then round const static U32 zpfp[] = { 0xBEFFFFFF, 0x3EFFFFFF }; @@ -166,7 +166,7 @@ inline S32 lltrunc( F64 f ) inline S32 llfloor( F32 f ) { -#if LL_WINDOWS && !defined( __INTEL_COMPILER ) +#if LL_WINDOWS && !defined( __INTEL_COMPILER ) && !defined(_WIN64) // Avoids changing the floating point control word. // Accurate (unlike Stereopsis version) for all values between S32_MIN and S32_MAX and slightly faster than Stereopsis version. // Add -(0.5 - epsilon) and then round diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h index cebd2ace7..798795a8b 100644 --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -31,7 +31,7 @@ #error "Please include llmath.h before this file." #endif -#if ( ( LL_DARWIN || LL_LINUX ) && !(__SSE2__) ) || ( LL_WINDOWS && ( _M_IX86_FP < 2 ) ) +#if ( ( LL_DARWIN || LL_LINUX ) && !(__SSE2__) ) || ( LL_WINDOWS && ( _M_IX86_FP < 2 ) && !defined(_WIN64) ) #error SSE2 not enabled. LLVector4a and related class will not compile. #endif diff --git a/indra/llmessage/aicurleasyrequeststatemachine.cpp b/indra/llmessage/aicurleasyrequeststatemachine.cpp index 0437055f5..294f41586 100644 --- a/indra/llmessage/aicurleasyrequeststatemachine.cpp +++ b/indra/llmessage/aicurleasyrequeststatemachine.cpp @@ -250,10 +250,13 @@ void AICurlEasyRequestStateMachine::finish_impl(void) } } -AICurlEasyRequestStateMachine::AICurlEasyRequestStateMachine(void) : +AICurlEasyRequestStateMachine::AICurlEasyRequestStateMachine(CWD_ONLY(bool debug)) : +#ifdef CWDEBUG + AIStateMachine(debug), +#endif mTotalDelayTimeout(AIHTTPTimeoutPolicy::getDebugSettingsCurlTimeout().getTotalDelay()) { - Dout(dc::statemachine, "Calling AICurlEasyRequestStateMachine(void) [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]"); + Dout(dc::statemachine(mSMDebug), "Calling AICurlEasyRequestStateMachine(void) [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]"); AICurlInterface::Stats::AICurlEasyRequestStateMachine_count++; } @@ -264,7 +267,7 @@ void AICurlEasyRequestStateMachine::setTotalDelayTimeout(F32 totalDelayTimeout) AICurlEasyRequestStateMachine::~AICurlEasyRequestStateMachine() { - Dout(dc::statemachine, "Calling ~AICurlEasyRequestStateMachine() [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]"); + Dout(dc::statemachine(mSMDebug), "Calling ~AICurlEasyRequestStateMachine() [" << (void*)this << "] [" << (void*)mCurlEasyRequest.get() << "]"); --AICurlInterface::Stats::AICurlEasyRequestStateMachine_count; } diff --git a/indra/llmessage/aicurleasyrequeststatemachine.h b/indra/llmessage/aicurleasyrequeststatemachine.h index 662efbe20..9bab7166b 100644 --- a/indra/llmessage/aicurleasyrequeststatemachine.h +++ b/indra/llmessage/aicurleasyrequeststatemachine.h @@ -52,7 +52,7 @@ // Construction of a AICurlEasyRequestStateMachine might throw AICurlNoEasyHandle. class AICurlEasyRequestStateMachine : public AIStateMachine, public AICurlEasyHandleEvents { public: - AICurlEasyRequestStateMachine(void); + AICurlEasyRequestStateMachine(CWD_ONLY(bool debug = false)); // Transparent access. AICurlEasyRequest mCurlEasyRequest; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index dfbc9e249..749c5df6f 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -343,6 +343,7 @@ void LLHTTPClient::ResponderBase::decode_llsd_body(U32 status, std::string const strncmp(str, "cap not found:", 14) && // Most of the other 3%. str[0] && // Empty happens too and aint LLSD either. strncmp(str, "Not Found", 9) && + strncmp(str, "Upstream error: ", 16) && // Received by LLEventPollResponder every 50 seconds (see http://wiki.secondlife.com/wiki/EventQueueGet). LLSDSerialize::fromXML(dummy, ss) > 0; if (server_sent_llsd_with_http_error) { diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp index 41a0310ce..a89fba530 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -294,14 +294,14 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp) //skip to LLPartData block U8 feh = 0; - for (U32 i = 0; i < size; ++i) + for (S32 i = 0; i < size; ++i) { dp.unpackU8(feh, "whippang"); } dp.unpackS32(size, "partsize"); //skip LLPartData block - for (U32 i = 0; i < size; ++i) + for (S32 i = 0; i < size; ++i) { dp.unpackU8(feh, "whippang"); } diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 446028b0f..5aa33696e 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -49,7 +49,7 @@ set_source_files_properties(${llplugin_HEADER_FILES} if(NOT WORD_SIZE EQUAL 32) if(WINDOWS) - add_definitions(/FIXED:NO) + # add_definitions(/FIXED:NO) else(WINDOWS) # not windows therefore gcc LINUX and DARWIN add_definitions(-fPIC) endif(WINDOWS) diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 597f07849..0db75a0e8 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -545,7 +545,7 @@ S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID) { mMaterialUpdatePending = true; mMaterialID = pMaterialID; - return TEM_CHANGE_NONE; + return TEM_CHANGE_TEXTURE; } mMaterialUpdatePending = false; diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index cbd8665d3..19edcaa27 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -38,7 +38,7 @@ const S32 TEM_CHANGE_NONE = 0x0; const S32 TEM_CHANGE_COLOR = 0x1; const S32 TEM_CHANGE_TEXTURE = 0x2; -const S32 TEM_CHANGE_MEDIA = 0x4; //Currently doesn't do anything, (not that TEM_CHANGE_TEXTURE either) +const S32 TEM_CHANGE_MEDIA = 0x4; const S32 TEM_INVALID = 0x8; const S32 TEM_BUMPMAP_COUNT = 32; @@ -133,7 +133,13 @@ public: virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; } + F32 getScaleS() const { return mScaleS; } + F32 getScaleT() const { return mScaleT; } + void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; } + F32 getOffsetS() const { return mOffsetS; } + F32 getOffsetT() const { return mOffsetT; } + F32 getRotation() const { return mRotation; } void getRotation(F32 *theta) const { *theta = mRotation; } @@ -144,7 +150,7 @@ public: U8 getBumpShinyFullbright() const { return mBump; } U8 getMediaFlags() const { return mMediaFlags & TEM_MEDIA_MASK; } - U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; } + LLTextureEntry::e_texgen getTexGen() const { return LLTextureEntry::e_texgen(mMediaFlags & TEM_TEX_GEN_MASK); } U8 getMediaTexGen() const { return mMediaFlags; } F32 getGlow() const { return mGlow; } const LLMaterialID& getMaterialID() const { return mMaterialID; }; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index ae78758b4..8b5310beb 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -755,10 +755,12 @@ bool LLGLManager::initGL() #endif stop_glerror(); +#if LL_WINDOWS if (mIsIntel && mGLVersion <= 3.f) { //never try to use framebuffer objects on older intel drivers (crashy) mHasFramebufferObject = FALSE; } +#endif stop_glerror(); diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index e4b7fb7c0..843789ae1 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -550,7 +550,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL; } } - + LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL; if (filename.empty()) @@ -610,6 +610,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade text[count++] = strdup("#define ATTRIBUTE attribute\n"); text[count++] = strdup("#define VARYING varying\n"); text[count++] = strdup("#define VARYING_FLAT varying\n"); + // Need to enable extensions here instead of in the shader files, + // before any non-preprocessor directives (per spec) + text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n"); + text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n"); } else if (minor_version <= 29) { @@ -620,6 +624,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade text[count++] = strdup("#define ATTRIBUTE attribute\n"); text[count++] = strdup("#define VARYING varying\n"); text[count++] = strdup("#define VARYING_FLAT varying\n"); + // Need to enable extensions here instead of in the shader files, + // before any non-preprocessor directives (per spec) + text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n"); + text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n"); } } else @@ -628,6 +636,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade { //set version to 1.30 text[count++] = strdup("#version 130\n"); + // Need to enable extensions here instead of in the shader files, + // before any non-preprocessor directives (per spec) + text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n"); + text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n"); + //some implementations of GLSL 1.30 require integer precision be explicitly declared text[count++] = strdup("precision mediump int;\n"); @@ -636,7 +649,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade else { //set version to 400 text[count++] = strdup("#version 400\n"); + // Need to enable extensions here instead of in the shader files, + // before any non-preprocessor directives (per spec) + text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n"); + text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n"); } + text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n"); text[count++] = strdup("#define FXAA_GLSL_130 1\n"); diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 64d003f0b..7c8e1afeb 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -171,9 +171,10 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * LLXMLNodePtr child; for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { - if (child->hasName("combo_item")) + if (child->hasName("combo_item") || child->hasName("combo_box.item")) { std::string label = child->getTextContents(); + child->getAttributeString("label", label); std::string value = label; child->getAttributeString("value", value); diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 7817fd0d5..e5242f7db 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -366,6 +366,20 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f } } +bool LLFocusMgr::keyboardFocusHasAccelerators() const +{ + LLView* focus_view = dynamic_cast(mKeyboardFocus); + while(focus_view) + { + if (focus_view->hasAccelerators()) + { + return true; + } + + focus_view = focus_view->getParent(); + } + return false; +} void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor ) { diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 5f1466f5d..7e5e50dfb 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -121,6 +121,7 @@ public: void unlockFocus(); BOOL focusLocked() const { return mLockedView != NULL; } + bool keyboardFocusHasAccelerators() const; struct Impl; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index c501d865c..deebb57e9 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -626,12 +626,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask) { // the menu items are in the child list in bottom up order LLView* prev_menu_item = parent_menu->findNextSibling(this); - return prev_menu_item ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE; + return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE; } else { LLView* next_menu_item = parent_menu->findPrevSibling(this); - return next_menu_item ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE; + return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE; } } @@ -641,12 +641,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask) if (y > getRect().getHeight() / 2) { LLView* prev_menu_item = parent_menu->findNextSibling(this); - return prev_menu_item ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE; + return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE; } else { LLView* next_menu_item = parent_menu->findPrevSibling(this); - return next_menu_item ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE; + return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE; } } @@ -3306,50 +3306,16 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) menu->getParent()->sendChildToFront(menu); } -//----------------------------------------------------------------------------- -// class LLPieMenuBranch -// A branch to another pie menu -//----------------------------------------------------------------------------- -class LLPieMenuBranch : public LLMenuItemGL -{ -public: - LLPieMenuBranch(const std::string& name, const std::string& label, LLPieMenu* branch); - - virtual LLXMLNodePtr getXML(bool save_children = true) const; - - // called to rebuild the draw label - virtual void buildDrawLabel( void ); - - virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) - { - LLMenuItemGL::handleMouseUp(x,y,mask); - return TRUE; - } - - // doIt() - do the primary funcationality of the menu item. - virtual void doIt( void ); - - LLPieMenu* getBranch() { return mBranch; } - -protected: - LLPieMenu* mBranch; -}; - -const F32 PIE_MENU_WIDTH = 190; -const F32 PIE_MENU_HEIGHT = 190; - -LLPieMenuBranch::LLPieMenuBranch(const std::string& name, - const std::string& label, - LLPieMenu* branch) +LLContextMenuBranch::LLContextMenuBranch(const std::string& name, const std::string& label, LLContextMenu* branch) : LLMenuItemGL( name, label, KEY_NONE, MASK_NONE ), mBranch( branch ) { - mBranch->hide(FALSE); + mBranch->hide(); mBranch->setParentMenuItem(this); } // virtual -LLXMLNodePtr LLPieMenuBranch::getXML(bool save_children) const +LLXMLNodePtr LLContextMenuBranch::getXML(bool save_children) const { if (mBranch) { @@ -3360,7 +3326,7 @@ LLXMLNodePtr LLPieMenuBranch::getXML(bool save_children) const } // called to rebuild the draw label -void LLPieMenuBranch::buildDrawLabel( void ) +void LLContextMenuBranch::buildDrawLabel( void ) { { // default enablement is this -- if any of the subitems are @@ -3386,62 +3352,72 @@ void LLPieMenuBranch::buildDrawLabel( void ) std::string st = mDrawAccelLabel; appendAcceleratorString( st ); mDrawAccelLabel = st; - - // No special branch suffix - mDrawBranchLabel.clear(); + + // Singu Note: This is meaningless to pies + mDrawBranchLabel = LLMenuGL::BRANCH_SUFFIX; +} + +void LLContextMenuBranch::showSubMenu() +{ + if (getDrawTextDisabled()) return; // Singu Note: Don't open disabled submenus! + S32 center_x; + S32 center_y; + static LLUICachedControl context("LiruUseContextMenus", false); + if (context) // Use the edge of this item + { + localPointToScreen(getRect().getWidth(), getRect().getHeight(), ¢er_x, ¢er_y); + } + else // Use the center of the parent pie menu, and hide it + { + LLContextMenu* parent = static_cast(getParent()); + const LLRect& rect = parent->getRect(); + parent->localPointToScreen(rect.getWidth() / 2, rect.getHeight() / 2, ¢er_x, ¢er_y); + parent->hide(); + } + mBranch->show(center_x, center_y, context); } // doIt() - do the primary funcationality of the menu item. -void LLPieMenuBranch::doIt( void ) +void LLContextMenuBranch::doIt( void ) { - LLPieMenu *parent = (LLPieMenu *)getParent(); - - LLRect rect = parent->getRect(); - S32 center_x; - S32 center_y; - parent->localPointToScreen(rect.getWidth() / 2, rect.getHeight() / 2, ¢er_x, ¢er_y); - - parent->hide(FALSE); - mBranch->show( center_x, center_y, FALSE ); + showSubMenu(); } +void LLContextMenuBranch::setHighlight( BOOL highlight ) +{ + if (highlight == getHighlight()) return; + LLMenuItemGL::setHighlight(highlight); + + // Singu Note: Pie menus show subs only on click + static LLUICachedControl context("LiruUseContextMenus", false); + if (!context) return; + + if (highlight) + { + showSubMenu(); + } + else + { + mBranch->hide(); + } +} + +/////////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- -// class LLPieMenu -// A circular menu of items, icons, etc. +// class LLContextMenu +// A context menu //----------------------------------------------------------------------------- -LLPieMenu::LLPieMenu(const std::string& name, const std::string& label) -: LLMenuGL(name, label), - mFirstMouseDown(FALSE), - mUseInfiniteRadius(FALSE), - mHoverItem(NULL), - mHoverThisFrame(FALSE), +LLContextMenu::LLContextMenu(const std::string& name, const std::string& label) +: LLMenuGL(name, label.empty() ? name : label), mHoveredAnyItem(FALSE), - mOuterRingAlpha(1.f), - mCurRadius(0.f), - mRightMouseDown(FALSE) -{ - setRect(LLRect(0,PIE_MENU_HEIGHT,PIE_MENU_WIDTH,0)); + mHoverItem(NULL) +{ + //setBackgroundVisible(TRUE); LLMenuGL::setVisible(FALSE); } -LLPieMenu::LLPieMenu(const std::string& name) -: LLMenuGL(name, name), - mFirstMouseDown(FALSE), - mUseInfiniteRadius(FALSE), - mHoverItem(NULL), - mHoverThisFrame(FALSE), - mHoveredAnyItem(FALSE), - mOuterRingAlpha(1.f), - mCurRadius(0.f), - mRightMouseDown(FALSE) -{ - setRect(LLRect(0,PIE_MENU_HEIGHT,PIE_MENU_WIDTH,0)); - LLMenuGL::setVisible(FALSE); -} - - // virtual -LLXMLNodePtr LLPieMenu::getXML(bool save_children) const +LLXMLNodePtr LLContextMenu::getXML(bool save_children) const { LLXMLNodePtr node = LLMenuGL::getXML(); @@ -3450,22 +3426,34 @@ LLXMLNodePtr LLPieMenu::getXML(bool save_children) const return node; } -void LLPieMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory) +void LLContextMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory, bool is_context) { LLXMLNodePtr child; for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { if (child->hasName(LL_PIE_MENU_TAG)) { - // SUBMENU - std::string name("menu"); - child->getAttributeString("name", name); - std::string label(name); - child->getAttributeString("label", label); + // In context menus, more submenu is just an extension of the parent + bool more(false); + if (is_context && child->getAttribute_bool("more", more) && more) + { + //addSeparator(); // Singu Note: perhaps a separator (above) is in order, too? + initXML(child, context, factory, true); + //addSeparator(); // Singu Note: perhaps a separator (below) is in order, too? + } + else + { + // SUBMENU + std::string name("menu"); + child->getAttributeString("name", name); + std::string label(name); + child->getAttributeString("label", label); - LLPieMenu *submenu = new LLPieMenu(name, label); - appendPieMenu(submenu); - submenu->initXML(child, context, factory); + // Singu Note: Pie Submenus are denoted with >, while context submenus have an obvious arrow at the end + LLContextMenu* submenu = is_context ? new LLContextMenu(name, label) : new LLPieMenu(name, label + " >"); + appendContextSubMenu(submenu); + submenu->initXML(child, context, factory, is_context); + } } else { @@ -3474,51 +3462,132 @@ void LLPieMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *fac } } -bool LLPieMenu::addChild(LLView* view, S32 tab_group) -{ - if(LLMenuGL::addChild(view, tab_group)) - { - LLMenuItemSeparatorGL* sep = dynamic_cast(view); - if(sep) - sep->setVisible(false); - return true; - } - return false; -} - // virtual -void LLPieMenu::setVisible(BOOL visible) +void LLContextMenu::setVisible(BOOL visible) { if (!visible) { - hide(FALSE); + hide(); } } -BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask ) +void LLContextMenu::show(S32 x, S32 y, bool context) { - // This is mostly copied from the llview class, but it continues - // the hover handle code after a hover handler has been found. - BOOL handled = FALSE; - - // If we got a hover event, we've already moved the cursor - // for any menu shifts, so subsequent mouseup messages will be in the - // correct position. No need to correct them. - //mShiftHoriz = 0; - //mShiftVert = 0; - - // release mouse capture after short period of visibility if we're using a finite boundary - // so that right click outside of boundary will trigger new pie menu - if (hasMouseCapture() && - !mRightMouseDown && - mShrinkBorderTimer.getStarted() && - mShrinkBorderTimer.getElapsedTimeF32() >= PIE_SHRINK_TIME) + if (getChildList()->empty()) { - gFocusMgr.setMouseCapture(NULL); - mUseInfiniteRadius = FALSE; + // nothing to show, so abort + return; + } + // Save click point for detecting cursor moves before mouse-up. + // Must be in local coords to compare with mouseUp events. + // If the mouse doesn't move, the menu will stay open ala the Mac. + // See also LLMenuGL::showPopup() + LLMenuHolderGL::sContextMenuSpawnPos.set(x,y); + + arrangeAndClear(); + + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); + const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); + LLView* parent_view = getParent(); + + // Singu TODO: These could probably be combined a bit more. + if (context) // Singu Note: Determine menu repositioning behavior based on menu type + { + // Open upwards if menu extends past bottom + if (y - height < menu_region_rect.mBottom) + { + if (getParentMenuItem()) + { + y += height - getParentMenuItem()->getNominalHeight(); + } + else + { + y += height; + } + } + + // Open out to the left if menu extends past right edge + if (x + width > menu_region_rect.mRight) + { + if (getParentMenuItem()) + { + x -= getParentMenuItem()->getRect().getWidth() + width; + } + else + { + x -= width; + } + } + + S32 local_x, local_y; + parent_view->screenPointToLocal(x, y, &local_x, &local_y); + + LLRect rect; + rect.setLeftTopAndSize(local_x, local_y, width, height); + setRect(rect); + } + else + { + S32 local_x, local_y; + parent_view->screenPointToLocal(x, y, &local_x, &local_y); + + LLRect rect; + rect.setCenterAndSize(local_x, local_y, width, height); + setRect(rect); + if (!menu_region_rect.contains(rect)) // Adjust the pie rectangle to keep it on screen + { + S32 trans[2]={0,0}; + if (rect.mLeft < menu_region_rect.mLeft) + { + trans[0] = menu_region_rect.mLeft - rect.mLeft; + } + else if (rect.mRight > menu_region_rect.mRight) + { + trans[0] = menu_region_rect.mRight - rect.mRight; + } + if (rect.mBottom < menu_region_rect.mBottom) + { + trans[1] = menu_region_rect.mBottom - rect.mBottom; + } + else if (rect.mTop > menu_region_rect.mTop) + { + trans[1] = menu_region_rect.mTop - rect.mTop; + } + setRect(rect.translate(trans[0],trans[1])); + LLUI::setMousePositionLocal(getParent(),rect.getCenterX(), rect.getCenterY()); + } } - LLMenuItemGL *item = pieItemFromXY( x, y ); + arrange(); + LLView::setVisible(TRUE); +} + +void LLContextMenu::hide() +{ + if (!getVisible()) return; + + LLView::setVisible(FALSE); + + if (mHoverItem) + { + mHoverItem->setHighlight( FALSE ); + mHoverItem = NULL; + } +} + +BOOL LLContextMenu::handleHover( S32 x, S32 y, MASK mask ) +{ + LLMenuGL::handleHover(x, y, mask); + + LLMenuItemGL* item = getHighlightedItem(); + + return handleHoverOver(item, x, y); +} + +BOOL LLContextMenu::handleHoverOver(LLMenuItemGL* item, S32 x, S32 y) +{ + BOOL handled = FALSE; if (item && item->getEnabled()) { @@ -3534,37 +3603,6 @@ BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask ) } mHoverItem = item; mHoverItem->setHighlight( TRUE ); - - switch(pieItemIndexFromXY(x, y)) - { - case 0: - make_ui_sound("UISndPieMenuSliceHighlight0"); - break; - case 1: - make_ui_sound("UISndPieMenuSliceHighlight1"); - break; - case 2: - make_ui_sound("UISndPieMenuSliceHighlight2"); - break; - case 3: - make_ui_sound("UISndPieMenuSliceHighlight3"); - break; - case 4: - make_ui_sound("UISndPieMenuSliceHighlight4"); - break; - case 5: - make_ui_sound("UISndPieMenuSliceHighlight5"); - break; - case 6: - make_ui_sound("UISndPieMenuSliceHighlight6"); - break; - case 7: - make_ui_sound("UISndPieMenuSliceHighlight7"); - break; - default: - make_ui_sound("UISndPieMenuSliceHighlight0"); - break; - } } mHoveredAnyItem = TRUE; } @@ -3585,8 +3623,170 @@ BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask ) handled = TRUE; } + return handled; +} + +// handleMouseUp and handleMouseDown are handled by LLMenuGL + + +BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL handled = FALSE; + + // The click was somewhere within our rectangle + LLMenuItemGL* item = getHighlightedItem(); + + S32 local_x = x - getRect().mLeft; + S32 local_y = y - getRect().mBottom; + + BOOL clicked_in_menu = pointInView(local_x, local_y); + + // grab mouse if right clicking anywhere within pie (even deadzone in middle), to detect drag outside of pie + if (clicked_in_menu) + { + // capture mouse cursor as if on initial menu show + handled = TRUE; + } + + if (item) + { + // lie to the item about where the click happened + // to make sure it's within the item's rectangle + if (item->handleMouseDown( 0, 0, mask )) + { + handled = TRUE; + } + } + + return handled; +} + +BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask ) +{ + S32 local_x = x - getRect().mLeft; + S32 local_y = y - getRect().mBottom; + + if (!mHoveredAnyItem && !pointInView(local_x, local_y)) + { + sMenuContainer->hideMenus(); + return TRUE; + } + + + BOOL result = handleMouseUp( x, y, mask ); + mHoveredAnyItem = FALSE; + + return result; +} + +bool LLContextMenu::addChild(LLView* view, S32 tab_group) +{ + if (LLContextMenu* context = dynamic_cast(view)) + return appendContextSubMenu(context); + if (LLMenuItemGL* item = dynamic_cast(view)) + return append(item); + if (LLMenuGL* menu = dynamic_cast(view)) + return appendMenu(menu); + return false; +} + + +BOOL LLContextMenu::appendContextSubMenu(LLContextMenu* menu) +{ + if (menu == this) + { + llerrs << "Can't attach a context menu to itself" << llendl; + } + LLContextMenuBranch* item = new LLContextMenuBranch(menu->getName(), menu->getLabel(), menu); + getParent()->addChild(item->getBranch()); + return append(item); +} + +const S32 PIE_MENU_HEIGHT = 190; +const S32 PIE_MENU_WIDTH = 190; + +//----------------------------------------------------------------------------- +// class LLPieMenu +// A circular menu of items, icons, etc. +//----------------------------------------------------------------------------- +LLPieMenu::LLPieMenu(const std::string& name, const std::string& label) +: LLContextMenu(name, label), + mFirstMouseDown(FALSE), + mUseInfiniteRadius(FALSE), + mHoverIndex(-1), + mHoverThisFrame(FALSE), + mOuterRingAlpha(1.f), + mCurRadius(0.f), + mRightMouseDown(FALSE) +{ + setRect(LLRect(0,PIE_MENU_HEIGHT,PIE_MENU_WIDTH,0)); +} + +// Separators on pie menus are invisible +bool LLPieMenu::addChild(LLView* view, S32 tab_group) +{ + if (LLContextMenu::addChild(view, tab_group)) + { + LLMenuItemSeparatorGL* sep = dynamic_cast(view); + if(sep) + sep->setVisible(false); + return true; + } + return false; +} + +BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask ) +{ + // release mouse capture after short period of visibility if we're using a finite boundary + // so that right click outside of boundary will trigger new pie menu + if (hasMouseCapture() && + !mRightMouseDown && + mShrinkBorderTimer.getStarted() && + mShrinkBorderTimer.getElapsedTimeF32() >= PIE_SHRINK_TIME) + { + gFocusMgr.setMouseCapture(NULL); + mUseInfiniteRadius = FALSE; + } + mHoverThisFrame = TRUE; + S32 index = mHoverIndex; + mHoverIndex = pieItemIndexFromXY(x, y); + BOOL handled = handleHoverOver(pieItemFromIndex(mHoverIndex), x, y); + + if (mHoverItem && mHoverIndex != index) + { + switch(mHoverIndex) + { + case 0: + make_ui_sound("UISndPieMenuSliceHighlight0"); + break; + case 1: + make_ui_sound("UISndPieMenuSliceHighlight1"); + break; + case 2: + make_ui_sound("UISndPieMenuSliceHighlight2"); + break; + case 3: + make_ui_sound("UISndPieMenuSliceHighlight3"); + break; + case 4: + make_ui_sound("UISndPieMenuSliceHighlight4"); + break; + case 5: + make_ui_sound("UISndPieMenuSliceHighlight5"); + break; + case 6: + make_ui_sound("UISndPieMenuSliceHighlight6"); + break; + case 7: + make_ui_sound("UISndPieMenuSliceHighlight7"); + break; + default: + make_ui_sound("UISndPieMenuSliceHighlight0"); + break; + } + } return handled; } @@ -3602,11 +3802,6 @@ BOOL LLPieMenu::handleMouseDown( S32 x, S32 y, MASK mask ) // to make sure it's within the item's rectangle handled = item->handleMouseDown( 0, 0, mask ); } - else if (!mRightMouseDown) - { - // call hidemenus to make sure transient selections get cleared - ((LLMenuHolderGL*)getParent())->hideMenus(); - } // always handle mouse down as mouse up will close open menus return TRUE; @@ -3688,13 +3883,26 @@ BOOL LLPieMenu::handleMouseUp( S32 x, S32 y, MASK mask ) if (item->getEnabled()) { handled = item->handleMouseUp( 0, 0, mask ); - hide(TRUE); + hide(); } } else if (!mRightMouseDown) { + // if shift is held, click is in the view, and a parent menu exists, go back up + if (mask & MASK_SHIFT && pointInView(x, y)) + { + if (LLMenuItemGL* branch = getParentMenuItem()) + { + if (LLContextMenu* parent = dynamic_cast(branch->getParent())) + { + hide(); + parent->show(LLMenuHolderGL::sContextMenuSpawnPos.mX, LLMenuHolderGL::sContextMenuSpawnPos.mY, false); + return true; + } + } + } // call hidemenus to make sure transient selections get cleared - ((LLMenuHolderGL*)getParent())->hideMenus(); + sMenuContainer->hideMenus(); } if (handled) @@ -3732,6 +3940,7 @@ void LLPieMenu::draw() { mHoverItem->setHighlight(FALSE); mHoverItem = NULL; + mHoverIndex = -1; } F32 width = (F32) getRect().getWidth(); @@ -3765,22 +3974,16 @@ void LLPieMenu::draw() gl_washer_2d( mCurRadius, (F32) PIE_CENTER_SIZE, steps, bg_color, outer_color ); // selected wedge - item_list_t::iterator item_iter; - S32 i = 0; - for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) + if (mHoverItem) { - if ((*item_iter)->getHighlight()) - { - F32 arc_size = F_PI * 0.25f; + F32 arc_size = F_PI * 0.25f; - F32 start_radians = (i * arc_size) - (arc_size * 0.5f); - F32 end_radians = start_radians + arc_size; + F32 start_radians = (mHoverIndex * arc_size) - (arc_size * 0.5f); + F32 end_radians = start_radians + arc_size; - LLColor4 outer_color = selected_color; - outer_color.mV[VALPHA] *= mOuterRingAlpha; - gl_washer_segment_2d( mCurRadius, (F32)PIE_CENTER_SIZE, start_radians, end_radians, steps / 8, selected_color, outer_color ); - } - i++; + LLColor4 outer_color = selected_color; + outer_color.mV[VALPHA] *= mOuterRingAlpha; + gl_washer_segment_2d( mCurRadius, (F32)PIE_CENTER_SIZE, start_radians, end_radians, steps / 8, selected_color, outer_color ); } LLUI::setLineWidth( line_width ); @@ -3807,38 +4010,10 @@ void LLPieMenu::draw() LLView::draw(); } -void LLPieMenu::drawBackground(LLMenuItemGL* itemp, LLColor4& color) +// virtual +void LLPieMenu::drawBackground(LLMenuItemGL*, LLColor4&) { - F32 width = (F32) getRect().getWidth(); - F32 height = (F32) getRect().getHeight(); - F32 center_x = width/2; - F32 center_y = height/2; - S32 steps = 100; - - gGL.color4fv( color.mV ); - gGL.pushUIMatrix(); - { - gGL.translateUI(center_x - itemp->getRect().mLeft, center_y - itemp->getRect().mBottom, 0.f); - - item_list_t::iterator item_iter; - S32 i = 0; - for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) - { - if ((*item_iter) == itemp) - { - F32 arc_size = F_PI * 0.25f; - - F32 start_radians = (i * arc_size) - (arc_size * 0.5f); - F32 end_radians = start_radians + arc_size; - - LLColor4 outer_color = color; - outer_color.mV[VALPHA] *= mOuterRingAlpha; - gl_washer_segment_2d( mCurRadius, (F32)PIE_CENTER_SIZE, start_radians, end_radians, steps / 8, color, outer_color ); - } - i++; - } - } - gGL.popUIMatrix(); + // Selection is drawn in our draw call, do nothing here and override base drawing rectangles. } // virtual @@ -3853,24 +4028,9 @@ BOOL LLPieMenu::append(LLMenuItemGL *item) BOOL LLPieMenu::addSeparator() { LLMenuItemGL* separator = new LLMenuItemBlankGL(); - separator->setFont( LLFontGL::getFontSansSerifSmall() ); return append( separator ); } - -BOOL LLPieMenu::appendPieMenu(LLPieMenu *menu) -{ - if (menu == this) - { - llerrs << "Can't attach a pie menu to itself" << llendl; - } - LLPieMenuBranch *item; - item = new LLPieMenuBranch(menu->getName(), menu->getLabel(), menu); - getParent()->addChild(item->getBranch()); - item->setFont( LLFontGL::getFontSansSerifSmall() ); - return append( item ); -} - // virtual void LLPieMenu::arrange() { @@ -3925,13 +4085,15 @@ void LLPieMenu::arrange() LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y) { - // We might have shifted this menu on draw. If so, we need - // to shift over mouseup events until we get a hover event. - //x += mShiftHoriz; - //y += mShiftVert; + return pieItemFromIndex(pieItemIndexFromXY(x, y)); +} +S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) +{ // An arc of the pie menu is 45 degrees const F32 ARC_DEG = 45.f; + + // correct for non-square pixels S32 delta_x = x - getRect().getWidth() / 2; S32 delta_y = y - getRect().getHeight() / 2; @@ -3939,14 +4101,14 @@ LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y) S32 dist_squared = delta_x*delta_x + delta_y*delta_y; if (dist_squared < PIE_CENTER_SIZE*PIE_CENTER_SIZE) { - return NULL; + return -1; } // infinite radius is only used with right clicks S32 radius = llmax( getRect().getWidth()/2, getRect().getHeight()/2 ); if (!(mUseInfiniteRadius && mRightMouseDown) && dist_squared > radius * radius) { - return NULL; + return -1; } F32 angle = RAD_TO_DEG * (F32) atan2((F32)delta_y, (F32)delta_x); @@ -3958,8 +4120,11 @@ LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y) // make sure we're only using positive angles if (angle < 0.f) angle += 360.f; - S32 which = S32( angle / ARC_DEG ); + return S32( angle / ARC_DEG ); +} +LLMenuItemGL* LLPieMenu::pieItemFromIndex(S32 which) +{ if (0 <= which && which < (S32)mItems.size() ) { item_list_t::iterator item_iter; @@ -3979,74 +4144,11 @@ LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y) return NULL; } -S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) + +// virtual +void LLPieMenu::show(S32 x, S32 y, bool mouse_down) { - // An arc of the pie menu is 45 degrees - const F32 ARC_DEG = 45.f; - // correct for non-square pixels - S32 delta_x = x - getRect().getWidth() / 2; - S32 delta_y = y - getRect().getHeight() / 2; - - // circle safe zone in the center - if (delta_x*delta_x + delta_y*delta_y < PIE_CENTER_SIZE*PIE_CENTER_SIZE) - { - return -1; - } - - F32 angle = RAD_TO_DEG * (F32) atan2((F32)delta_y, (F32)delta_x); - - // rotate marks CCW so that east = [0, ARC_DEG) instead of - // [-ARC_DEG/2, ARC_DEG/2) - angle += ARC_DEG / 2.f; - - // make sure we're only using positive angles - if (angle < 0.f) angle += 360.f; - - S32 which = S32( angle / ARC_DEG ); - return which; -} - -void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) -{ - S32 width = getRect().getWidth(); - S32 height = getRect().getHeight(); - - const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); - - LLView* parent_view = getParent(); - - S32 local_x, local_y; - parent_view->screenPointToLocal(x, y, &local_x, &local_y); - - LLRect rect; - rect.setCenterAndSize(local_x, local_y, width, height); - setRect(rect); - - arrange(); - - // Adjust the pie rectangle to keep it on screen - if(!menu_region_rect.contains(rect)) - { - S32 trans[2]={0,0}; - if (rect.mLeft < menu_region_rect.mLeft) - { - trans[0] = menu_region_rect.mLeft - rect.mLeft; - } - else if (rect.mRight > menu_region_rect.mRight) - { - trans[0] = menu_region_rect.mRight - rect.mRight; - } - if (rect.mBottom < menu_region_rect.mBottom) - { - trans[1] = menu_region_rect.mBottom - rect.mBottom; - } - else if (rect.mTop > menu_region_rect.mTop) - { - trans[1] = menu_region_rect.mTop - rect.mTop; - } - setRect(rect.translate(trans[0],trans[1])); - LLUI::setMousePositionLocal(getParent(),rect.getCenterX(), rect.getCenterY()); - } + LLContextMenu::show(x, y, false); // *FIX: what happens when mouse buttons reversed? mRightMouseDown = mouse_down; @@ -4059,8 +4161,6 @@ void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) make_ui_sound("UISndPieMenuAppear"); } - LLView::setVisible(TRUE); - // we want all mouse events in case user does quick right click again off of pie menu // rectangle, to support gestural menu traversal gFocusMgr.setMouseCapture(this); @@ -4075,16 +4175,10 @@ void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) } } -void LLPieMenu::hide(BOOL item_selected) +// virtual +void LLPieMenu::hide() { - if (!getVisible()) return; - - if (mHoverItem) - { - mHoverItem->setHighlight( FALSE ); - mHoverItem = NULL; - } - + LLContextMenu::hide(); make_ui_sound("UISndPieMenuHide"); mFirstMouseDown = FALSE; @@ -4092,8 +4186,6 @@ void LLPieMenu::hide(BOOL item_selected) mUseInfiniteRadius = FALSE; mHoveredAnyItem = FALSE; - LLView::setVisible(FALSE); - gFocusMgr.setMouseCapture(NULL); } @@ -4630,10 +4722,13 @@ BOOL LLMenuHolderGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) } else { - //highlight first enabled one - if(pMenu->highlightNextItem(NULL)) + if (key == KEY_UP || key == KEY_DOWN) // Singu Note: Only highlight if the user actually meant to navigate through the menu { - handled = true; + //highlight first enabled one + if (pMenu->highlightNextItem(NULL)) + { + handled = true; + } } } } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 07effab8d..9fd6868b7 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -685,29 +685,59 @@ private: +//----------------------------------------------------------------------------- +// class LLContextMenu +// A context menu +//----------------------------------------------------------------------------- +class LLContextMenu +: public LLMenuGL +{ +public: + LLContextMenu(const std::string& name, const std::string& label = ""); + + virtual LLXMLNodePtr getXML(bool save_children = true) const; + void initXML(LLXMLNodePtr node, LLView* context, LLUICtrlFactory* factory, bool is_context); + +public: + virtual ~LLContextMenu() {} + + // LLView Functionality + // can't set visibility directly, must call show or hide + virtual void setVisible(BOOL visible); + + virtual void show(S32 x, S32 y, bool context = true); + virtual void hide(); + + virtual BOOL handleHover( S32 x, S32 y, MASK mask ); + BOOL handleHoverOver(LLMenuItemGL* item, S32 x, S32 y); // Singu Note: Unify common functionality between Pie and Context hover behaviors + virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); + virtual BOOL handleRightMouseUp( S32 x, S32 y, MASK mask ); + + virtual bool addChild(LLView* view, S32 tab_group = 0); + + BOOL appendContextSubMenu(LLContextMenu* menu); + +protected: + BOOL mHoveredAnyItem; + LLMenuItemGL* mHoverItem; +}; + //----------------------------------------------------------------------------- // class LLPieMenu // A circular menu of items, icons, etc. //----------------------------------------------------------------------------- class LLPieMenu -: public LLMenuGL +: public LLContextMenu { public: - LLPieMenu(const std::string& name, const std::string& label); - LLPieMenu(const std::string& name); + LLPieMenu(const std::string& name, const std::string& label = ""); virtual ~LLPieMenu() {} - virtual LLXMLNodePtr getXML(bool save_children = true) const; - void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory); - // LLView Functionality // hide separators. they are added to 'pad' in empty cells. virtual bool addChild(LLView* view, S32 tab_group = 0); - // can't set visibility directly, must call show or hide - virtual void setVisible(BOOL visible); - virtual BOOL handleHover( S32 x, S32 y, MASK mask ); virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); @@ -721,34 +751,59 @@ private: public: virtual BOOL addSeparator(); - BOOL appendPieMenu(LLPieMenu *menu); - virtual void arrange( void ); // Display the menu centered on this point on the screen. - void show(S32 x, S32 y, BOOL mouse_down); - void hide(BOOL item_selected); + /*virtual*/ void show(S32 x, S32 y, bool mouse_down = true); + /*virtual*/ void hide(); private: LLMenuItemGL *pieItemFromXY(S32 x, S32 y); + LLMenuItemGL* pieItemFromIndex(S32 which); S32 pieItemIndexFromXY(S32 x, S32 y); - // These cause menu items to be spuriously selected by right-clicks - // near the window edge at low frame rates. I don't think they are - // needed unless you shift the menu position in the draw() function. JC - //S32 mShiftHoriz; // non-zero if menu had to shift this frame - //S32 mShiftVert; // non-zero if menu had to shift this frame BOOL mFirstMouseDown; // true from show until mouse up BOOL mUseInfiniteRadius; // allow picking pie menu items anywhere outside of center circle - LLMenuItemGL* mHoverItem; + S32 mHoverIndex; BOOL mHoverThisFrame; - BOOL mHoveredAnyItem; LLFrameTimer mShrinkBorderTimer; F32 mOuterRingAlpha; // for rendering pie menus as both bounded and unbounded F32 mCurRadius; BOOL mRightMouseDown; }; +//----------------------------------------------------------------------------- +// class LLContextMenuBranch +// A branch to another context menu +//----------------------------------------------------------------------------- +class LLContextMenuBranch : public LLMenuItemGL +{ +public: + LLContextMenuBranch(const std::string& name, const std::string& label, LLContextMenu* branch); + + virtual LLXMLNodePtr getXML(bool save_children = true) const; + + // called to rebuild the draw label + virtual void buildDrawLabel( void ); + + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) + { + LLMenuItemGL::handleMouseUp(x,y,mask); + return TRUE; + } + + // doIt() - do the primary funcationality of the menu item. + virtual void doIt( void ); + + LLContextMenu* getBranch() { return mBranch; } + void setHighlight( BOOL highlight ); + +protected: + void showSubMenu(); + + LLContextMenu* mBranch; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuBarGL diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index 07b811f71..1db97fe7c 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -187,7 +187,8 @@ BOOL LLMultiFloater::closeAllFloaters() //Tab did not actually close, possibly due to a pending Save Confirmation dialog.. //so try and close the next one in the list... tabToClose++; - }else + } + else { //Tab closed ok. lastTabCount = mTabContainer->getTabCount(); @@ -252,7 +253,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, else if (floaterp->getHost()) { // floaterp is hosted by somebody else and - // this is adding it, so remove it from it's old host + // this is adding it, so remove it from its old host floaterp->getHost()->removeFloater(floaterp); } else if (floaterp->getParent() == gFloaterView) @@ -302,8 +303,21 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, { floaterp->setVisible(FALSE); } + + // Tabs sometimes overlap resize handle + moveResizeHandlesToFront(); } +void LLMultiFloater::updateFloaterTitle(LLFloater* floaterp) +{ + S32 index = mTabContainer->getIndexForPanel(floaterp); + if (index != -1) + { + mTabContainer->setPanelTitle(index, floaterp->getShortTitle()); + } +} + + /** BOOL selectFloater(LLFloater* floaterp) @@ -329,8 +343,9 @@ void LLMultiFloater::selectPrevFloater() mTabContainer->selectPrevTab(); } -void LLMultiFloater::showFloater(LLFloater* floaterp) +void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertionPoint insertion_point) { + if(!floaterp) return; // we won't select a panel that already is selected // it is hard to do this internally to tab container // as tab selection is handled via index and the tab at a given @@ -338,7 +353,7 @@ void LLMultiFloater::showFloater(LLFloater* floaterp) if (floaterp != mTabContainer->getCurrentPanel() && !mTabContainer->selectTabPanel(floaterp)) { - addFloater(floaterp, TRUE); + addFloater(floaterp, TRUE, insertion_point); } } @@ -417,6 +432,13 @@ BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask) if (floater && floater->canClose() && floater->isCloseable()) { floater->close(); + + // EXT-5695 (Tabbed IM window loses focus if close any tabs by Ctrl+W) + // bring back focus on tab container if there are any tab left + if(mTabContainer->getTabCount() > 0) + { + mTabContainer->setFocus(TRUE); + } } return TRUE; } @@ -468,12 +490,17 @@ void LLMultiFloater::setFloaterFlashing(LLFloater* floaterp, BOOL flashing) void LLMultiFloater::onTabSelected() { - tabOpen((LLFloater*)mTabContainer->getCurrentPanel()); + LLFloater* floaterp = dynamic_cast(mTabContainer->getCurrentPanel()); + if (floaterp) + { + tabOpen(floaterp); + } } void LLMultiFloater::setCanResize(BOOL can_resize) { LLFloater::setCanResize(can_resize); + if (!mTabContainer) return; if (isResizable() && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM) { mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH); @@ -510,16 +537,9 @@ void LLMultiFloater::updateResizeLimits() // initialize minimum size constraint to the original xml values. S32 new_min_width = mOrigMinWidth; S32 new_min_height = mOrigMinHeight; - // possibly increase minimum size constraint due to children's minimums. - for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) - { - LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx); - if (floaterp) - { - new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2); - new_min_height = llmax(new_min_height, floaterp->getMinHeight() + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT); - } - } + + computeResizeLimits(new_min_width, new_min_height); + setResizeLimits(new_min_width, new_min_height); S32 cur_height = getRect().getHeight(); @@ -545,3 +565,17 @@ void LLMultiFloater::updateResizeLimits() gFloaterView->adjustToFitScreen(this, TRUE); } } + +void LLMultiFloater::computeResizeLimits(S32& new_min_width, S32& new_min_height) +{ + // possibly increase minimum size constraint due to children's minimums. + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx); + if (floaterp) + { + new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2); + new_min_height = llmax(new_min_height, floaterp->getMinHeight() + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT); + } + } +} diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index e56b387bc..b18ff292a 100644 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -56,7 +56,7 @@ public: virtual void growToFit(S32 content_width, S32 content_height); virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); - virtual void showFloater(LLFloater* floaterp); + virtual void showFloater(LLFloater* floaterp, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); virtual void removeFloater(LLFloater* floaterp); virtual void tabOpen(LLFloater* opened_floater); @@ -76,6 +76,7 @@ public: void onTabSelected(); virtual void updateResizeLimits(); + virtual void updateFloaterTitle(LLFloater* floaterp); protected: struct LLFloaterData @@ -94,6 +95,9 @@ protected: LLTabContainer::TabPosition mTabPos; BOOL mAutoResize; S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late + +private: + virtual void computeResizeLimits(S32& new_min_width, S32& new_min_height); }; #endif // LL_MULTI_FLOATER_H diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 41254b0bb..b8fab0994 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -40,6 +40,7 @@ #include "lltrans.h" #include "llnotifications.h" +#include "aialert.h" #include "../newview/hippogridmanager.h" @@ -1479,6 +1480,14 @@ LLNotificationPtr LLNotifications::add(const LLNotification::Params& p) return pNotif; } +namespace AIAlert { std::string text(Error const& error, int suppress_mask = 0); } +LLNotificationPtr LLNotifications::add(AIAlert::Error const& error, int type, unsigned int suppress_mask) +{ + LLSD substitutions = LLSD::emptyMap(); + substitutions["[PAYLOAD]"] = AIAlert::text(error, suppress_mask); + return add(LLNotification::Params((type == AIAlert::modal || error.is_modal()) ? "AIAlertModal" : "AIAlert").substitutions(substitutions)); +} + void LLNotifications::add(const LLNotificationPtr pNotif) { diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index fe9049ee2..bb769cae7 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -108,6 +108,8 @@ #include "llnotificationptr.h" #include "llnotificationcontext.h" +namespace AIAlert { class Error; } + typedef enum e_notification_priority { NOTIFICATION_PRIORITY_UNSPECIFIED, @@ -737,6 +739,7 @@ public: const LLSD& substitutions, const LLSD& payload, LLNotificationFunctorRegistry::ResponseFunctor functor); + LLNotificationPtr add(AIAlert::Error const& error, int type, unsigned int suppress_mask); LLNotificationPtr add(const LLNotification::Params& p); void forceResponse(const LLNotification::Params& params, S32 option); diff --git a/indra/llui/llnotificationsutil.cpp b/indra/llui/llnotificationsutil.cpp index 4abc9ca69..4c24b511e 100644 --- a/indra/llui/llnotificationsutil.cpp +++ b/indra/llui/llnotificationsutil.cpp @@ -25,11 +25,76 @@ #include "linden_common.h" #include "llnotificationsutil.h" +#include "lltrans.h" #include "llnotifications.h" #include "llsd.h" #include "llxmlnode.h" // apparently needed to call LLNotifications::instance() +namespace AIAlert +{ + +LLNotificationPtr add(Error const& error, unsigned int suppress_mask, modal_nt type) +{ + return LLNotifications::instance().add(error, type, suppress_mask); +} + +LLNotificationPtr add(std::string const& xml_desc, modal_nt type) +{ + return LLNotifications::instance().add(Error(Prefix(), type, xml_desc, AIArgs()), type, 0); +} + +LLNotificationPtr add(std::string const& xml_desc, AIArgs const& args, modal_nt type) +{ + return LLNotifications::instance().add(Error(Prefix(), type, xml_desc, args), type, 0); +} + +LLNotificationPtr add(Error const& error, std::string const& xml_desc, unsigned int suppress_mask, modal_nt type) +{ + return LLNotifications::instance().add(Error(Prefix(), type, error, xml_desc, AIArgs()), type, suppress_mask); +} + +LLNotificationPtr add(Error const& error, std::string const& xml_desc, AIArgs const& args, unsigned int suppress_mask, modal_nt type) +{ + return LLNotifications::instance().add(Error(Prefix(), type, error, xml_desc, args), type, suppress_mask); +} + +LLNotificationPtr add(std::string const& xml_desc, Error const& error, unsigned int suppress_mask, modal_nt type) +{ + return LLNotifications::instance().add(Error(Prefix(), type, xml_desc, AIArgs(), error), type, suppress_mask); +} + +LLNotificationPtr add(std::string const& xml_desc, AIArgs const& args, Error const& error, unsigned int suppress_mask, modal_nt type) +{ + return LLNotifications::instance().add(Error(Prefix(), type, xml_desc, args, error), type, suppress_mask); +} + +std::string text(Error const& error, int suppress_mask) +{ + std::string alert_text; + bool suppress_newlines = false; + bool last_was_prefix = false; + for (Error::lines_type::const_iterator line = error.lines().begin(); line != error.lines().end(); ++line) + { + // Even if a line is suppressed, we print its leading newline if requested, but never more than one. + if (!suppress_newlines && line->prepend_newline()) + { + alert_text += '\n'; + suppress_newlines = true; + } + if (!line->suppressed(suppress_mask)) + { + if (last_was_prefix) alert_text += ' '; // The translation system strips off spaces... add them back. + alert_text += LLTrans::getString(line->getXmlDesc(), line->args()); + suppress_newlines = false; + last_was_prefix = line->is_prefix(); + } + } + return alert_text; +} + +} // namespace AIAlert + LLNotificationPtr LLNotificationsUtil::add(const std::string& name) { return LLNotifications::instance().add( diff --git a/indra/llui/llnotificationsutil.h b/indra/llui/llnotificationsutil.h index 4093324d0..893d2269c 100644 --- a/indra/llui/llnotificationsutil.h +++ b/indra/llui/llnotificationsutil.h @@ -30,11 +30,55 @@ // to avoid including the heavyweight llnotifications.h #include "llnotificationptr.h" +#include "aialert.h" #include class LLSD; +namespace AIAlert +{ + // Add an alert directly to LLNotifications. + + // Look up xml_desc in strings.xml. + LLNotificationPtr add(std::string const& xml_desc, + modal_nt type = not_modal); + // ... with replacement args. + LLNotificationPtr add(std::string const& xml_desc, AIArgs const& args, + modal_nt type = not_modal); + + // Append it to an existing alert error. + LLNotificationPtr add(Error const& error, + std::string const& xml_desc, + unsigned int suppress_mask = 0, modal_nt type = not_modal); + LLNotificationPtr add(Error const& error, + std::string const& xml_desc, AIArgs const& args, + unsigned int suppress_mask = 0, modal_nt type = not_modal); + // Prepend it to an existing alert error. + LLNotificationPtr add(std::string const& xml_desc, + Error const& error, + unsigned int suppress_mask = 0, modal_nt type = not_modal); + LLNotificationPtr add(std::string const& xml_desc, AIArgs const& args, + Error const& error, + unsigned int suppress_mask = 0, modal_nt type = not_modal); + + // Just show the caught alert error. + LLNotificationPtr add(Error const& error, + unsigned int suppress_mask = 0, modal_nt type = not_modal); + + // Short cuts for enforcing modal alerts. + inline LLNotificationPtr add_modal(std::string const& xml_desc) { return add(xml_desc, modal); } + inline LLNotificationPtr add_modal(std::string const& xml_desc, AIArgs const& args) { return add(xml_desc, args, modal); } + inline LLNotificationPtr add_modal(Error const& error, std::string const& xml_desc, unsigned int suppress_mask = 0) { return add(error, xml_desc, suppress_mask, modal); } + inline LLNotificationPtr add_modal(Error const& error, std::string const& xml_desc, AIArgs const& args, unsigned int suppress_mask = 0) { return add(error, xml_desc, args, suppress_mask, modal); } + inline LLNotificationPtr add_modal(std::string const& xml_desc, Error const& error, unsigned int suppress_mask = 0) { return add(xml_desc, error, suppress_mask, modal); } + inline LLNotificationPtr add_modal(std::string const& xml_desc, AIArgs const& args, Error const& error, unsigned int suppress_mask = 0) { return add(xml_desc, args, error, suppress_mask, modal); } + inline LLNotificationPtr add_modal(Error const& error, unsigned int suppress_mask = 0) { return add(error, suppress_mask, modal); } + + // Return the full, translated, texted of the alert (possibly suppressing certain output). + std::string text(Error const& error, int suppress_mask = 0); +} + namespace LLNotificationsUtil { LLNotificationPtr add(const std::string& name); diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index c6ff2fa03..66d09954d 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -530,11 +530,13 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f void LLPanel::initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory) { + std::string kidstring(node->getName()->mString); + kidstring += ".string"; LLXMLNodePtr child; for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) { // look for string declarations for programmatic text - if (child->hasName("string")) + if (child->hasName("string") || child->hasName(kidstring)) { std::string string_name; child->getAttributeString("name", string_name); diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index 6353528c4..59c991512 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -40,9 +40,10 @@ const S32 MIN_COLUMN_WIDTH = 20; //--------------------------------------------------------------------------- // LLScrollColumnHeader //--------------------------------------------------------------------------- -LLScrollColumnHeader::LLScrollColumnHeader(const std::string& name, const LLRect& rect, LLScrollListColumn* column) -: LLButton(name, rect, "square_btn_32x128.tga", "square_btn_selected_32x128.tga", LLStringUtil::null, NULL, LLFontGL::getFontSansSerifSmall()), +LLScrollColumnHeader::LLScrollColumnHeader(const std::string& name, const LLRect& rect, LLScrollListColumn* column, const std::string& unselected_image_name, const std::string& selected_image_name) +: LLButton(name, rect, unselected_image_name, selected_image_name, LLStringUtil::null, NULL, LLFontGL::getFontSansSerifSmall()), mColumn(column), + mDrawArrow(true), mHasResizableElement(FALSE) { setClickedCallback(boost::bind(&LLScrollColumnHeader::onClick, this, _2)); @@ -65,20 +66,23 @@ LLScrollColumnHeader::~LLScrollColumnHeader() void LLScrollColumnHeader::draw() { - std::string sort_column = mColumn->mParentCtrl->getSortColumnName(); - BOOL draw_arrow = !mColumn->mLabel.empty() - && mColumn->mParentCtrl->isSorted() - // check for indirect sorting column as well as column's sorting name - && (sort_column == mColumn->mSortingColumn || sort_column == mColumn->mName); + if (mDrawArrow) + { + std::string sort_column = mColumn->mParentCtrl->getSortColumnName(); + BOOL draw_arrow = !mColumn->mLabel.empty() + && mColumn->mParentCtrl->isSorted() + // check for indirect sorting column as well as column's sorting name + && (sort_column == mColumn->mSortingColumn || sort_column == mColumn->mName); - BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); - if (draw_arrow) - { - setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, LLColor4::white); - } - else - { - setImageOverlay(LLUUID::null); + BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); + if (draw_arrow) + { + setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, LLColor4::white); + } + else + { + setImageOverlay(LLUUID::null); + } } // Draw children diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h index 2026e075c..c7cea5976 100644 --- a/indra/llui/llscrolllistcolumn.h +++ b/indra/llui/llscrolllistcolumn.h @@ -40,7 +40,7 @@ class LLScrollListCtrl; class LLScrollColumnHeader : public LLButton { public: - LLScrollColumnHeader(const std::string& name, const LLRect& rect, LLScrollListColumn* column); + LLScrollColumnHeader(const std::string& name, const LLRect& rect, LLScrollListColumn* column, const std::string& unselected_image_name = "square_btn_32x128.tga", const std::string& selected_image_name = "square_btn_selected_32x128.tga"); ~LLScrollColumnHeader(); /*virtual*/ void draw(); @@ -51,6 +51,8 @@ public: /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false); LLScrollListColumn* getColumn() { return mColumn; } + // Singu Note: Toggles drawing the sort arrow altogether + void setDrawArrow(bool draw_arrow) { mDrawArrow = draw_arrow; } void setHasResizableElement(BOOL resizable); void updateResizeBars(); BOOL canResize(); @@ -60,6 +62,7 @@ public: private: LLScrollListColumn* mColumn; + bool mDrawArrow; LLResizeBar* mResizeBar; BOOL mHasResizableElement; }; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index f76b21762..bae86672c 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2848,24 +2848,29 @@ void LLScrollListCtrl::addColumn(const LLScrollListColumn::Params& column_params LLRect temp_rect = LLRect(left,top+mHeadingHeight,right,top); - new_column->mHeader = new LLScrollColumnHeader("btn_" + name, temp_rect, new_column); - new_column->mHeader->setToolTip(column_params.tool_tip()); - new_column->mHeader->setTabStop(false); - new_column->mHeader->setVisible(mDisplayColumnHeaders); - - if(column_params.header.image.isProvided()) + if (column_params.header.image.isProvided()) { - new_column->mHeader->setImages(column_params.header.image, column_params.header.image); - } - else if(column_params.header.image_overlay.isProvided()) - { - new_column->mHeader->setImageOverlay(column_params.header.image_overlay); + new_column->mHeader = new LLScrollColumnHeader("btn_" + name, temp_rect, new_column, column_params.header.image, column_params.header.image); + new_column->mHeader->setDrawArrow(false); } else { - new_column->mHeader->setLabel(column_params.header.label()); + new_column->mHeader = new LLScrollColumnHeader("btn_" + name, temp_rect, new_column); + if (column_params.header.image_overlay.isProvided()) + { + new_column->mHeader->setImageOverlay(column_params.header.image_overlay); + new_column->mHeader->setDrawArrow(false); + } + else + { + new_column->mHeader->setLabel(column_params.header.label()); + } } + new_column->mHeader->setToolTip(column_params.tool_tip()); + new_column->mHeader->setTabStop(false); + new_column->mHeader->setVisible(mDisplayColumnHeaders); + addChild(new_column->mHeader); sendChildToFront(mScrollbar); diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index d5bb963d4..9cd8aa9d8 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -446,7 +446,7 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const std::string &filename, LLView* parent //----------------------------------------------------------------------------- // buildMenu() //----------------------------------------------------------------------------- -LLPieMenu *LLUICtrlFactory::buildPieMenu(const std::string &filename, LLView* parentp) +LLContextMenu* LLUICtrlFactory::buildContextMenu(const std::string& filename, LLView* parentp) { LLXMLNodePtr root; @@ -465,9 +465,10 @@ LLPieMenu *LLUICtrlFactory::buildPieMenu(const std::string &filename, LLView* pa std::string name("menu"); root->getAttributeString("name", name); - LLPieMenu *menu = new LLPieMenu(name); + static LLUICachedControl context("LiruUseContextMenus", false); + LLContextMenu* menu = context ? new LLContextMenu(name) : new LLPieMenu(name); parentp->addChild(menu); - menu->initXML(root, parentp, this); + menu->initXML(root, parentp, this, context); if (LLUI::sShowXUINames) { diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 3fac2bdb5..b3ef3aeeb 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -106,7 +106,7 @@ public: bool builtPanel(LLPanel* panelp) {return mBuiltPanels.find(panelp->getHandle()) != mBuiltPanels.end();} class LLMenuGL *buildMenu(const std::string &filename, LLView* parentp); - class LLPieMenu *buildPieMenu(const std::string &filename, LLView* parentp); + class LLContextMenu* buildContextMenu(const std::string& filename, LLView* parentp); // Does what you want for LLFloaters and LLPanels // Returns 0 on success diff --git a/indra/llui/llview.h b/indra/llui/llview.h index b009bab41..cc7ce21eb 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -357,6 +357,11 @@ public: BOOL focusNextRoot(); BOOL focusPrevRoot(); + // Normally we want the app menus to get priority on accelerated keys + // However, sometimes we want to give specific views a first chance + // at handling them. (eg. the script editor) + virtual bool hasAccelerators() const { return false; } + virtual void deleteAllChildren(); virtual void setTentative(BOOL b); diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index a93c833ba..c3a042247 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -363,7 +363,11 @@ std::string LLDir::buildSLOSCacheDir() const } else { +#if defined(_WIN64) + res = add(getOSCacheDir(), "SingularityViewer64"); +#else res = add(getOSCacheDir(), "SingularityViewer"); +#endif } return res; } diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 78f54a7a4..807c547bd 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -749,7 +749,7 @@ void LLWindowWin32::close() LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; // Don't process events in our mainWindowProc any longer. - SetWindowLong(mWindowHandle, GWL_USERDATA, NULL); + SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL); // Make sure we don't leave a blank toolbar button. ShowWindow(mWindowHandle, SW_HIDE); @@ -1660,7 +1660,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO LL_DEBUGS("Window") << "Keeping vertical sync" << LL_ENDL; } - SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this); + SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, (LONG_PTR)this); // register this window as handling drag/drop events from the OS DragAcceptFiles( mWindowHandle, TRUE ); @@ -1983,7 +1983,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // This helps prevent avatar walking after maximizing the window by double-clicking the title bar. static bool sHandleLeftMouseUp = true; - LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(h_wnd, GWL_USERDATA); + LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr(h_wnd, GWLP_USERDATA); if (NULL != window_imp) diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index 535cfc010..be0a510b4 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -13,6 +13,7 @@ include_directories( ) set(llxml_SOURCE_FILES + aixml.cpp llcontrol.cpp llxmlnode.cpp llxmlparser.cpp @@ -22,6 +23,7 @@ set(llxml_SOURCE_FILES set(llxml_HEADER_FILES CMakeLists.txt + aixml.h llcontrol.h llcontrolgroupreader.h llxmlnode.h diff --git a/indra/llxml/aixml.cpp b/indra/llxml/aixml.cpp new file mode 100644 index 000000000..d7592c431 --- /dev/null +++ b/indra/llxml/aixml.cpp @@ -0,0 +1,609 @@ +/** + * @file aixml.cpp + * @brief XML serialization support. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 30/07/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#include "sys.h" +#include "aixml.h" +#include "llmd5.h" +#include +#include "aifile.h" + +//============================================================================= +// Overview + +// The AIXML* classes provide an Object Oriented way to serialize objects +// to and from an XML file. +// +// The following classes are provided: +// +// AIXMLRootElement - Write an object to a file (including XML declaration at the top). +// AIXMLElement - Write an ojbect to an ostream (just one XML element). +// +// AIXMLParser - Read and deserialize an XML file written with AIXMLRootElement. +// AIXMLElementParser - Read and deserialize an XML stream written with AIXMLElement. +// +// Classes that need to be written to and from XML would typically +// supply two member functions. For example, + +#ifdef EXAMPLE_CODE // undefined + +class HelloWorld { + public: + // Write object to XML. + void toXML(std::ostream& os, int indentation) const; + // Read object from XML. + HelloWorld(AIXMLElementParser const& parser); + + private: + // Example member variables... + Attribute1 mAttribute1; + Attribute2 mAttribute2; + // etc. + Custom1 mCustom; + std::vector mContainer; + LLDate mDate; + LLMD5 mMd5; + LLUUID mUUID; +}; + +// Typical serialization member function. +void HelloWorld::toXML(std::ostream& os, int indentation) const +{ + AIXMLElement tag(os, "helloworld", indentation); + + // Zero or more attributes: + tag.attribute("attributename1", mAttribute1); // Uses operator<<(std::ostream&, Attribute1 const&) to write mAttribute1. + tag.attribute("attributename2", mAttribute2); // Uses operator<<(std::ostream&, Attribute2 const&) to write mAttribute2. + // etc. + + // Zero or more child elements: + tag.child("tagname", mChild1); + tag.child(mCustom); // Calls mCustom.toXML() to insert the object. + tag.child(mContainer.begin(), mContainer.end()); // Calls tag.child(element) for each element of the container. + // Special allowed cases: + tag.child(mDate); // Uses "date" as tag name. + tag.child(mMd5); // Uses "md5" as tag name. + tag.child(mUUID); // Uses "uuid" as tag name. +} + +// Typical deserialization member function. +HelloWorld::HelloWorld(AIXMLElementParser const& parser) +{ + // Zero or more attributes: + parser.attribute("attributename1", "foobar"); // Throws std::runtime_error is attributename1 is missing or does not have the value "foobar". + if (!parser.attribute("attributename2", mAttribute2)) // Reads value of attributename2 into mAttribute2 (throws if it could not be parsed). + { + throw std::runtime_error("..."); // Attribute was missing. + } + + // Zero or more child elements: + parser.child("tagname", mChild1); + parser.child("custom1", mCustom); + parser.insert_children("custom2", mContainer); + // Special allowed cases: + parser.child(mDate); + parser.child(mMd5); + parser.child(mUUID); +} + +// To actually write to an XML file one would do, for example: + + LLFILE* fp = fopen(...); + AIXMLRootElement tag(fp, "rootname"); + tag.attribute("version", "1.0"); + tag.child(LLDate::now()); + tag.child(mHelloWorld); + +// And to read it again, + + AIXMLParser helloworld(filename, "description of file used for error reporting", "rootname", 1); + helloworld.attribute("version", "1.0"); + helloworld.child("helloworld", mHelloWorld); + +// Of course, both would need to be in a try { } catch block. + +#endif // EXAMPLE_CODE + +// Do NOT change these - it would break old databases. +char const* const DEFAULT_LLUUID_NAME = "uuid"; +char const* const DEFAULT_MD5STR_NAME = "md5"; +char const* const DEFAULT_LLDATE_NAME = "date"; + +std::string const DEFAULT_MD5STR_ATTRIBUTE_NAME = DEFAULT_MD5STR_NAME; +std::string const DEFAULT_LLUUID_ATTRIBUTE_NAME = DEFAULT_LLUUID_NAME; +std::string const DEFAULT_LLDATE_ATTRIBUTE_NAME = DEFAULT_LLDATE_NAME; +std::string const DEFAULT_VERSION_ATTRIBUTE_NAME = "version"; + +struct xdigit { + bool isxdigit; + xdigit(void) : isxdigit(true) { } + void operator()(char c) { isxdigit = isxdigit && std::isxdigit(c); } + operator bool() const { return isxdigit; } +}; + +static bool is_valid_md5str(std::string const& str) +{ + return str.length() == MD5HEX_STR_BYTES && std::for_each(str.begin(), str.end(), xdigit()); +} + +// Conversion routine that is a lot more strict then LLStringUtil::convertToU32. +// This version does not allow leading or trailing spaces, nor does it allow a leading minus sign. +// Leading zeroes are not allowed except a 0 by itself. +bool convertToU32strict(std::string const& str, U32& value) +{ + bool first = true; + value = 0; + for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) + { + if (value == 0 && !first || !std::isdigit(*i)) // Reject leading zeroes and non-digits. + return false; + value = value * 10 + *i - '0'; + first = false; + } + return !first; // Reject empty string. +} + +typedef boost::tokenizer > boost_tokenizer; + +bool decode_version(std::string const& version, U32& major, U32& minor) +{ + boost_tokenizer tokens(version, boost::char_separator("", ".")); + boost_tokenizer::const_iterator itTok = tokens.begin(); + return itTok != tokens.end() && convertToU32strict(*itTok++, major) && + itTok != tokens.end() && *itTok++ == "." && + itTok != tokens.end() && convertToU32strict(*itTok, minor); +} + +bool md5strFromXML(LLXmlTreeNode* node, std::string& md5str_out) +{ + static LLStdStringHandle const DEFAULT_MD5STR_ATTRIBUTE_NAME_HANDLE = LLXmlTree::addAttributeString(DEFAULT_MD5STR_ATTRIBUTE_NAME); + return node->getFastAttributeString(DEFAULT_MD5STR_ATTRIBUTE_NAME_HANDLE, md5str_out) && is_valid_md5str(md5str_out); +} + +bool md5strFromXML(LLXmlTreeNode* node, std::string& md5str_out, std::string const& attribute_name) +{ + return node->getAttributeString(attribute_name, md5str_out) && is_valid_md5str(md5str_out); +} + +bool UUIDFromXML(LLXmlTreeNode* node, LLUUID& uuid_out) +{ + static LLStdStringHandle const DEFAULT_LLUUID_ATTRIBUTE_NAME_HANDLE = LLXmlTree::addAttributeString(DEFAULT_LLUUID_ATTRIBUTE_NAME); + return node->getFastAttributeUUID(DEFAULT_LLUUID_ATTRIBUTE_NAME_HANDLE, uuid_out); +} + +bool UUIDFromXML(LLXmlTreeNode* node, LLUUID& uuid_out, std::string const& attribute_name) +{ + return node->getAttributeUUID(attribute_name, uuid_out); +} + +bool dateFromXML(LLXmlTreeNode* node, LLDate& date_out) +{ + static LLStdStringHandle const DEFAULT_LLDATE_ATTRIBUTE_NAME_HANDLE = LLXmlTree::addAttributeString(DEFAULT_LLDATE_ATTRIBUTE_NAME); + std::string date_s; + return node->getFastAttributeString(DEFAULT_LLDATE_ATTRIBUTE_NAME_HANDLE, date_s) && date_out.fromString(date_s); +} + +bool dateFromXML(LLXmlTreeNode* node, LLDate& date_out, std::string const& attribute_name) +{ + std::string date_s; + return node->getAttributeString(attribute_name, date_s) && date_out.fromString(date_s); +} + +bool versionFromXML(LLXmlTreeNode* node, U32& major_out, U32& minor_out) +{ + static LLStdStringHandle const DEFAULT_VERSION_ATTRIBUTE_NAME_HANDLE = LLXmlTree::addAttributeString(DEFAULT_VERSION_ATTRIBUTE_NAME); + major_out = minor_out = 0; + std::string version_s; + return node->getFastAttributeString(DEFAULT_VERSION_ATTRIBUTE_NAME_HANDLE, version_s) && decode_version(version_s, major_out, minor_out); +} + +bool versionFromXML(LLXmlTreeNode* node, U32& major_out, U32& minor_out, std::string const& attribute_name) +{ + major_out = minor_out = 0; + std::string version_s; + return node->getAttributeString(attribute_name, version_s) && decode_version(version_s, major_out, minor_out); +} + +//----------------------------------------------------------------------------- +// AIXMLElement + +AIXMLElement::AIXMLElement(std::ostream& os, char const* name, int indentation) : + mOs(os), mName(name), mIndentation(indentation), mHasChildren(false) +{ + mOs << std::string(mIndentation, ' ') << '<' << mName; + if (!mOs.good()) + { + THROW_ALERT("AIXMLElement_Failed_to_write_DATA", AIArgs("[DATA]", "<" + mName)); + } +} + +int AIXMLElement::open_child(void) +{ + if (!mHasChildren) + { + mOs << ">\n"; + if (!mOs.good()) + { + THROW_ALERT("AIXMLElement_closing_child_Failed_to_write_DATA", AIArgs("[DATA]", ">\\n")); + } + mHasChildren = true; + } + mIndentation += 2; + return mIndentation; +} + +void AIXMLElement::close_child(void) +{ + mIndentation -= 2; +} + +AIXMLElement::~AIXMLElement() +{ + if (mHasChildren) + { + mOs << std::string(mIndentation, ' ') << "\n"; + if (!mOs.good()) + { + THROW_ALERT("AIXMLElement_closing_child_Failed_to_write_DATA", + AIArgs("[DATA]", "\\n" + std::string(mIndentation, ' ') + "\\n")); + } + } + else + { + mOs << " />\n"; + if (!mOs.good()) + { + THROW_ALERT("AIXMLElement_closing_child_Failed_to_write_DATA", AIArgs("[DATA]", " />\\n")); + } + } +} + +template<> +void AIXMLElement::child(LLUUID const& element) +{ + open_child(); + write_child(DEFAULT_LLUUID_NAME, element); + close_child(); +} + +template<> +void AIXMLElement::child(LLMD5 const& element) +{ + open_child(); + write_child(DEFAULT_MD5STR_NAME, element); + close_child(); +} + +template<> +void AIXMLElement::child(LLDate const& element) +{ + open_child(); + write_child(DEFAULT_LLDATE_NAME, element); + close_child(); +} + +//----------------------------------------------------------------------------- +// AIXMLStream + +AIXMLStream::AIXMLStream(LLFILE* fp, bool standalone) : mOfs(fp) +{ + char const* sp = standalone ? " standalone=\"yes\"" : ""; + int rc = fprintf(fp, "\n", sp); + if (rc < 0 || ferror(fp)) + { + // I don't think that errno is set to anything else but EBADF here, + // so there is not really any informative message to add here. + THROW_MALERT("AIXMLStream_fprintf_failed_to_write_xml_header"); + } +} + +AIXMLStream::~AIXMLStream() +{ + if (mOfs.is_open()) + { + mOfs.close(); + } +} + +//----------------------------------------------------------------------------- +// AIXMLParser + +AIXMLParser::AIXMLParser(std::string const& filename, char const* file_desc, std::string const& name, U32 major_version) : + AIXMLElementParser(mFilename, mFileDesc, major_version), + mFilename(filename), mFileDesc(file_desc) +{ + char const* error = NULL; + AIArgs args; + if (!mXmlTree.parseFile(filename, TRUE)) + { + AIFile dummy(filename, "rb"); // Check if the file can be opened at all (throws with a more descriptive error if not). + error = "AIXMLParser_Cannot_parse_FILEDESC_FILENAME"; + } + else + { + mNode = mXmlTree.getRoot(); + if (!mNode) + { + error = "AIXMLParser_No_root_node_found_in_FILEDESC_FILENAME"; + } + else if (!mNode->hasName(name)) + { + error = "AIXMLParser_Missing_header_NAME_invalid_FILEDESC_FILENAME"; + args("[NAME]", name); + } + else if (!versionFromXML(mNode, mVersionMajor, mVersionMinor)) + { + error = "AIXMLParser_Invalid_or_missing_NAME_version_attribute_in_FILEDESC_FILENAME"; + args("[NAME]", name); + } + else if (mVersionMajor != major_version) + { + error = "AIXMLParser_Incompatible_NAME_version_MAJOR_MINOR_in"; + args("[NAME]", name)("[MAJOR]", llformat("%u", mVersionMajor))("[MINOR]", llformat("%u", mVersionMinor)); + } + } + if (error) + { + THROW_MALERT(error, args("[FILEDESC]", mFileDesc)("[FILENAME]", mFilename)); + } +} + +//----------------------------------------------------------------------------- +// AIXMLElementParser + +template<> +LLMD5 AIXMLElementParser::read_string(std::string const& value) const +{ + if (!is_valid_md5str(value)) + { + THROW_MALERT("AIXMLElementParser_read_string_Invalid_MD5_VALUE_in_FILEDESC_FILENAME", + AIArgs("[VALUE]", value)("[FILEDESC]", mFileDesc)("[FILENAME]", mFilename)); + } + unsigned char digest[16]; + std::memset(digest, 0, sizeof(digest)); + for (int i = 0; i < 32; ++i) + { + int x = value[i]; + digest[i >> 1] += (x - (x & 0xf0) + (x >> 6) * 9) << ((~i & 1) << 2); + } + LLMD5 result; + result.clone(digest); + return result; +} + +template<> +LLDate AIXMLElementParser::read_string(std::string const& value) const +{ + LLDate result; + result.fromString(value); + return result; +} + +template +T AIXMLElementParser::read_integer(char const* type, std::string const& value) const +{ + long long int result; + sscanf(value.c_str(),"%lld", &result); + if (result < (std::numeric_limits::min)() || result > (std::numeric_limits::max)()) + { + THROW_MALERT("AIXMLElementParser_read_integer_Invalid_TYPE_VALUE_in_FILEDESC_FILENAME", + AIArgs("[TYPE]", type)("[VALUE]", value)("FILEDESC", mFileDesc)("[FILENAME]", mFilename)); + } + return result; +} + +template<> +U8 AIXMLElementParser::read_string(std::string const& value) const +{ + return read_integer("U8", value); +} + +template<> +S8 AIXMLElementParser::read_string(std::string const& value) const +{ + return read_integer("S8", value); +} + +template<> +U16 AIXMLElementParser::read_string(std::string const& value) const +{ + return read_integer("U16", value); +} + +template<> +S16 AIXMLElementParser::read_string(std::string const& value) const +{ + return read_integer("S16", value); +} + +template<> +U32 AIXMLElementParser::read_string(std::string const& value) const +{ + return read_integer("U32", value); +} + +template<> +S32 AIXMLElementParser::read_string(std::string const& value) const +{ + return read_integer("S32", value); +} + +double read_float(std::string const& value) +{ + double result; + sscanf(value.c_str(),"%lf", &result); + return result; +} + +template<> +F32 AIXMLElementParser::read_string(std::string const& value) const +{ + return read_float(value); +} + +template<> +F64 AIXMLElementParser::read_string(std::string const& value) const +{ + return read_float(value); +} + +template<> +bool AIXMLElementParser::read_string(std::string const& value) const +{ + if (value == "true") + { + return true; + } + else if (value != "false") + { + THROW_MALERT("AIXMLElementParser_read_string_Invalid_boolean_VALUE_in_FILEDESC_FILENAME", + AIArgs("[VALUE]", value)("FILEDESC]", mFileDesc)("[FILENAME]", mFilename)); + } + return false; +} + +void AIXMLElementParser::attribute(char const* name, char const* required_value) const +{ + char const* error = NULL; + AIArgs args; + std::string value; + if (!mNode->getAttributeString(name, value)) + { + error = "AIXMLElementParser_attribute_Missing_NAME_attribute_in_NODENAME_of_FILEDESC_FILENAME"; + } + else if (value != required_value) + { + error = "AIXMLElementParser_attribute_Invalid_NAME_attribute_should_be_REQUIRED_in_NODENAME_of_FILEDESC_FILENAME"; + args("[REQUIRED]", required_value); + } + if (error) + { + THROW_MALERT(error, args("[NAME]", name)("[NODENAME]", node_name())("[FILEDESC]", mFileDesc)("[FILENAME]", mFilename)); + } +} + +template<> +LLUUID AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + LLUUID result; + if (!LLUUID::parseUUID(node->getContents(), &result)) + { + THROW_MALERT("AIXMLElementParser_read_child_Invalid_uuid_in_FILEDESC_FILENAME", + AIArgs("[FILEDESC]", mFileDesc)("[FILENAME]", mFilename)); + } + return result; +} + +template<> +LLMD5 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_string(node->getContents()); +} + +template<> +LLDate AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + LLDate result; + if (!result.fromString(node->getContents())) + { + THROW_MALERT("AIXMLElementParser_read_child_Invalid_date_DATE_in_FILEDESC_FILENAME", + AIArgs("[DATE]", node->getContents())("[FILEDESC]", mFileDesc)("[FILENAME]", mFilename)); + } + return result; +} + +template<> +S8 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_integer("S8", node->getContents()); +} + +template<> +U8 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_integer("U8", node->getContents()); +} + +template<> +S16 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_integer("S16", node->getContents()); +} + +template<> +U16 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_integer("U16", node->getContents()); +} + +template<> +S32 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_integer("S32", node->getContents()); +} + +template<> +U32 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_integer("U32", node->getContents()); +} + +template<> +F32 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_string(node->getContents()); +} + +template<> +F64 AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_string(node->getContents()); +} + +template<> +bool AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return read_string(node->getContents()); +} + +bool AIXMLElementParser::child(LLUUID& uuid) const +{ + return child(DEFAULT_LLUUID_NAME, uuid); +} + +bool AIXMLElementParser::child(LLMD5& md5) const +{ + return child(DEFAULT_MD5STR_NAME, md5); +} + +bool AIXMLElementParser::child(LLDate& date) const +{ + return child(DEFAULT_LLDATE_NAME, date); +} + diff --git a/indra/llxml/aixml.h b/indra/llxml/aixml.h new file mode 100644 index 000000000..9bfb783f4 --- /dev/null +++ b/indra/llxml/aixml.h @@ -0,0 +1,375 @@ +/** + * @file aixml.h + * @brief XML serialization support. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 30/07/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AIXML_H +#define AIXML_H + +#include "llxmltree.h" +#include "llxmlnode.h" +#include "llfile.h" +#include +#include "aialert.h" + +extern char const* const DEFAULT_LLUUID_NAME; +extern char const* const DEFAULT_MD5STR_NAME; +extern char const* const DEFAULT_LLDATE_NAME; + +class LLUUID; +class LLMD5; +class LLDate; + +bool md5strFromXML(LLXmlTreeNode* node, std::string& md5str_out); +bool md5strFromXML(LLXmlTreeNode* node, std::string& md5str_out, std::string const& attribute_name); +bool UUIDFromXML(LLXmlTreeNode* node, LLUUID& uuid_out); +bool UUIDFromXML(LLXmlTreeNode* node, LLUUID& uuid_out, std::string const& attribute_name); +bool dateFromXML(LLXmlTreeNode* node, LLDate& date_out); +bool dateFromXML(LLXmlTreeNode* node, LLDate& date_out, std::string const& attribute_name); +bool versionFromXML(LLXmlTreeNode* node, U32& major_out, U32& minor_out); +bool versionFromXML(LLXmlTreeNode* node, U32& major_out, U32& minor_out, std::string const& attribute_name); + +class AIXMLElement +{ + private: + std::ostream& mOs; + std::string mName; + int mIndentation; + bool mHasChildren; + + public: + AIXMLElement(std::ostream& os, char const* name, int indentation); + ~AIXMLElement(); + + template + void attribute(char const* name, T const& attribute); + template + void child(T const& element); + template + void child(char const* name, T const& element); + template + void child(FWD_ITERATOR i1, FWD_ITERATOR const& i2); + + private: + template + void write_child(char const* name, T const& element); + + int open_child(void); + void close_child(void); +}; + +template +void AIXMLElement::attribute(char const* name, T const& attribute) +{ + std::ostringstream raw_attribute; + raw_attribute << attribute; + mOs << ' ' << name << "=\"" << LLXMLNode::escapeXML(raw_attribute.str()) << '"'; + if (!mOs.good()) + { + std::ostringstream ss; + ss << ' ' << name << "=\"" << LLXMLNode::escapeXML(raw_attribute.str()) << '"'; + THROW_FALERT("AIXMLElement_attribute_Failed_to_write_DATA", AIArgs("[DATA]", ss.str())); + } +} + +template +void AIXMLElement::child(T const& element) +{ + open_child(); + element.toXML(mOs, mIndentation); + if (!mOs.good()) // Normally toXML will already have thrown. + { + THROW_FALERT("AIXMLElement_child_Bad_ostream"); + } + close_child(); +} + +template<> +void AIXMLElement::child(LLUUID const& element); + +template<> +void AIXMLElement::child(LLMD5 const& element); + +template<> +void AIXMLElement::child(LLDate const& element); + +template +void AIXMLElement::write_child(char const* name, T const& element) +{ + mOs << std::string(mIndentation, ' ') << '<' << name << '>' << element << "\n"; + if (!mOs.good()) + { + std::ostringstream ss; + ss << std::string(mIndentation, ' ') << '<' << name << '>' << element << "\\n"; + THROW_FALERT("AIXMLElement_write_child_Failed_to_write_DATA", AIArgs("[DATA]", ss.str())); + } +} + +template +void AIXMLElement::child(char const* name, T const& element) +{ + open_child(); + write_child(name, element); + close_child(); +} + +template +void AIXMLElement::child(FWD_ITERATOR i1, FWD_ITERATOR const& i2) +{ + while (i1 != i2) + { + child(*i1++); + } +} + +// Helper class for AIXMLRootElement. +class AIXMLStream { + protected: + llofstream mOfs; + AIXMLStream(LLFILE* fp, bool standalone); + ~AIXMLStream(); +}; + +// Class to write XML files. +class AIXMLRootElement : public AIXMLStream, public AIXMLElement +{ + public: + AIXMLRootElement(LLFILE* fp, char const* name, bool standalone = true) : AIXMLStream(fp, standalone), AIXMLElement(mOfs, name, 0) { } +}; + +class AIXMLElementParser +{ + private: + U32 mVersion; + std::string const& mFilename; + std::string const& mFileDesc; + + protected: + LLXmlTreeNode* mNode; + + protected: + // Used by AIXMLParser, which initializes mNode directly. + AIXMLElementParser(std::string const& filename, std::string const& file_desc, U32 version) : mVersion(version), mFilename(filename), mFileDesc(file_desc) { } + virtual ~AIXMLElementParser() { } + + // Used for error reporting. + virtual std::string node_name(void) const { return "node '" + mNode->getName() + "'"; } + + // Parse the integer given as string 'value' and return it as type T (U8, S8, U16, S16, U32 or S32). + template + T read_integer(char const* type, std::string const& value) const; + + // Parse the string 'value' and return it as type T. + template + T read_string(std::string const& value) const; + + // Parse a child node and return it as type T. + template + T read_child(LLXmlTreeNode* node) const; + + public: + // Constructor for child member functions. + AIXMLElementParser(std::string const& filename, std::string const& file_desc, U32 version, LLXmlTreeNode* node) : mVersion(version), mFilename(filename), mFileDesc(file_desc), mNode(node) { } + + // Require the existence of some attribute with given value. + void attribute(char const* name, char const* required_value) const; + + // Read attribute. Returns true if attribute was found. + template + bool attribute(char const* name, T& attribute) const; + + // Read child element. Returns true if child was found. + template + bool child(char const* name, T& child) const; + // Read Linden types. Return true if the child was found. + bool child(LLUUID& uuid) const; + bool child(LLMD5& md5) const; + bool child(LLDate& date) const; + + // Append all elements with name 'name' to container. + template + void push_back_children(char const* name, CONTAINER& container) const; + + // Insert all elements with name 'name' into container. + template + void insert_children(char const* name, CONTAINER& container) const; + + // Set version of this particular element (if not set mVersion will be the version of the parent, all the way up to the xml header with a version of 1). + void setVersion(U32 version) { mVersion = version; } + + // Accessors. + std::string const& filename(void) const { return mFilename; } + std::string const& filedesc(void) const { return mFileDesc; } + U32 version(void) const { return mVersion; } +}; + +template +inline T AIXMLElementParser::read_string(std::string const& value) const +{ + // Construct from string. + return T(value); +} + +// Specializations. + +template<> +LLMD5 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +LLDate AIXMLElementParser::read_string(std::string const& value) const; + +template<> +U8 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +S8 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +U16 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +S16 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +U32 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +S32 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +F32 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +F64 AIXMLElementParser::read_string(std::string const& value) const; + +template<> +bool AIXMLElementParser::read_string(std::string const& value) const; + + +template +bool AIXMLElementParser::attribute(char const* name, T& attribute) const +{ + std::string value; + if (!mNode->getAttributeString(name, value)) + { + return false; + } + attribute = read_string(value); + return true; +} + +template +inline T AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return AIXMLElementParser(mFilename, mFileDesc, mVersion, node); +} + +// Specializations. + +template<> +inline std::string AIXMLElementParser::read_child(LLXmlTreeNode* node) const +{ + return node->getContents(); +} + +template<> +LLMD5 AIXMLElementParser::read_child(LLXmlTreeNode* node) const; + +template<> +LLUUID AIXMLElementParser::read_child(LLXmlTreeNode* node) const; + +template<> +LLDate AIXMLElementParser::read_child(LLXmlTreeNode* node) const; + +template<> +S32 AIXMLElementParser::read_child(LLXmlTreeNode* node) const; + +template<> +F32 AIXMLElementParser::read_child(LLXmlTreeNode* node) const; + +template<> +bool AIXMLElementParser::read_child(LLXmlTreeNode* node) const; + + +template +bool AIXMLElementParser::child(char const* name, T& child) const +{ + LLXmlTreeNode* node = mNode->getChildByName(name); + if (!node) + { + return false; + } + child = read_child(node); + return true; +} + +template +void AIXMLElementParser::insert_children(char const* name, CONTAINER& container) const +{ + for (LLXmlTreeNode* node = mNode->getFirstChild(); node; node = mNode->getNextChild()) + { + if (!node->hasName(name)) + continue; + container.insert(read_child(node)); + } +} + +template +void AIXMLElementParser::push_back_children(char const* name, CONTAINER& container) const +{ + for (LLXmlTreeNode* node = mNode->getFirstChild(); node; node = mNode->getNextChild()) + { + if (!node->hasName(name)) + continue; + container.push_back(read_child(node)); + } +} + +// Class to read XML files. +class AIXMLParser : public AIXMLElementParser +{ + private: + std::string mFilename; + std::string mFileDesc; + + LLXmlTree mXmlTree; + U32 mVersionMajor; + U32 mVersionMinor; + + public: + AIXMLParser(std::string const& filename, char const* file_desc, std::string const& name, U32 major_version); + + U32 version_major(void) const { return mVersionMajor; } + U32 version_minor(void) const { return mVersionMinor; } + + protected: + /*virtual*/ std::string node_name(void) const { return "root node"; } +}; + +#endif // AIXML_H + diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 259fa091f..006bf3e71 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -555,6 +555,36 @@ void XMLCALL EndXMLNode(void *userData, node->setValue(value); } } + // Singu note: moved here from XMLData. + if (LLXMLNode::sStripEscapedStrings) + { + std::string value = node->getValue(); + int len = value.length(); + if (len > 1 && value[0] == '"' && value[len - 1] == '"') + { + // Special-case: Escaped string. + std::string unescaped_string; + for (S32 pos = 1; pos < len - 1; ++pos) + { + if (value[pos] == '\\' && value[pos + 1] == '\\') + { + unescaped_string += '\\'; + ++pos; + } + else if (value[pos] == '\\' && value[pos + 1] == '"') + { + unescaped_string += '"'; + ++pos; + } + else + { + unescaped_string += value[pos]; + } + } + value += unescaped_string; + node->setValue(value); + } + } } void XMLCALL XMLData(void *userData, @@ -563,6 +593,15 @@ void XMLCALL XMLData(void *userData, { LLXMLNode* current_node = (LLXMLNode *)userData; std::string value = current_node->getValue(); +#if 0 + // Apparently also Lindens who write XML parsers can't read documentation. + // "A single block of contiguous text free of markup may still result in a sequence + // of calls to this handler. In other words, if you're searching for a pattern in + // the text, it may be split across calls to this handler." + // (http://sepp.oetiker.ch/expat-1.95.6-rs.SEPP/expat-1.95.6/doc/reference.html#XML_SetCharacterDataHandler) + // + // In other words, this is not guaranteed to work at all -- Aleric. + if (LLXMLNode::sStripEscapedStrings) { if (s[0] == '\"' && s[len-1] == '\"') @@ -591,6 +630,7 @@ void XMLCALL XMLData(void *userData, return; } } +#endif value.append(std::string(s, len)); current_node->setValue(value); } @@ -928,12 +968,6 @@ bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, return true; } -// static -void LLXMLNode::writeHeaderToFile(LLFILE *out_file) -{ - fprintf(out_file, "\n"); -} - void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent, bool use_type_decorations) { if (isFullyDefault()) diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index 78572603d..5898375e9 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -157,11 +157,6 @@ public: static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector& paths); - - // Write standard XML file header: - // - static void writeHeaderToFile(LLFILE *out_file); - // Write XML to file with one attribute per line. // XML escapes values as they are written. void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index edb6c8c9d..9238802f0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -38,6 +38,7 @@ include(LLXML) #include(LScript) include(Linking) include(NDOF) +include(NVAPI) include(StateMachine) include(TemplateCheck) include(UI) @@ -47,6 +48,8 @@ include(LLAppearance) if (WINDOWS) include(CopyWinLibs) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP) + include(InstallRequiredSystemLibraries) endif (WINDOWS) include_directories( @@ -80,6 +83,7 @@ include_directories( set(viewer_SOURCE_FILES NACLantispam.cpp aihttpview.cpp + aixmllindengenepool.cpp aoremotectrl.cpp ascentfloatercontactgroups.cpp ascentkeyword.cpp @@ -597,6 +601,7 @@ set(viewer_HEADER_FILES NACLantispam.h aihttpview.h + aixmllindengenepool.h aoremotectrl.h ascentfloatercontactgroups.h ascentkeyword.h @@ -1429,21 +1434,11 @@ if (!DISABLE_TEMPLATE_CHECK) check_message_template(${VIEWER_BINARY_NAME}) endif (!DISABLE_TEMPLATE_CHECK) -# We package by default on Linux so we can run from newview/packaged. -if (LINUX) - set(PACKAGE_DEFAULT ON) -else (LINUX) - set(PACKAGE_DEFAULT OFF) -endif (LINUX) -set(PACKAGE ${PACKAGE_DEFAULT} CACHE BOOL +set(PACKAGE OFF CACHE BOOL "Add a package target that builds an installer package.") if (WINDOWS) - if(MSVC10) - set(release_flags "/MAPRelease/${VIEWER_BINARY_NAME}.map") - else(MSVC10) - set(release_flags "/MAP:Release/${VIEWER_BINARY_NAME}.map") - endif(MSVC10) + set(release_flags "/MAPRelease/${VIEWER_BINARY_NAME}.map") if (FMOD) if(MANIFEST_LIBRARIES) @@ -1453,12 +1448,18 @@ if (WINDOWS) endif(MANIFEST_LIBRARIES) endif (FMOD) if (FMODEX) + if (WORD_SIZE EQUAL 32) + set(fmodex_dll_file "fmodex.dll") + else (WORD_SIZE EQUAL 32) + set(fmodex_dll_file "fmodex64.dll") + endif (WORD_SIZE EQUAL 32) + if(MANIFEST_LIBRARIES) - set(MANIFEST_LIBRARIES "${MANIFEST_LIBRARIES}|${FMODEX_BINARY_DIR}/fmodex.dll") + set(MANIFEST_LIBRARIES "${MANIFEST_LIBRARIES}|${FMODEX_BINARY_DIR}/${fmodex_dll_file}") else(MANIFEST_LIBRARIES) - set(MANIFEST_LIBRARIES "--extra_libraries=${FMODEX_BINARY_DIR}/fmodex.dll") + set(MANIFEST_LIBRARIES "--extra_libraries=${FMODEX_BINARY_DIR}/${fmodex_dll_file}") endif(MANIFEST_LIBRARIES) - set(EXTRA_LINKER_FLAGS "/DELAYLOAD:fmodex.dll") + set(EXTRA_LINKER_FLAGS "/DELAYLOAD:${fmodex_dll_file}") endif (FMODEX) set_target_properties(${VIEWER_BINARY_NAME} @@ -1516,6 +1517,7 @@ if (WINDOWS) COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py + --arch=${ARCH} --artwork=${ARTWORK_DIR} --branding_id=${VIEWER_BRANDING_ID} --build=${CMAKE_CURRENT_BINARY_DIR} @@ -1537,6 +1539,7 @@ if (WINDOWS) COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py + --arch=${ARCH} --artwork=${ARTWORK_DIR} --actions=copy --branding_id=${VIEWER_BRANDING_ID} @@ -1590,6 +1593,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLMATH_LIBRARIES} ${LLCOMMON_LIBRARIES} ${NDOF_LIBRARY} + ${NVAPI_LIBRARY} ${viewer_LIBRARIES} ${Boost_CONTEXT_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} @@ -1857,6 +1861,21 @@ endif (LL_TESTS) # Don't do these for DARWIN or LINUX here -- they're taken care of by viewer_manifest.py if (WINDOWS) + IF(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS) + FOREACH(RUNTIME_LIB ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}) + add_custom_command( + TARGET ${VIEWER_BINARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -E + copy_if_different + ${RUNTIME_LIB} + ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Copying ${RUNTIME_LIB} to the runtime folder." + ) + ENDFOREACH(RUNTIME_LIB ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}) + ENDIF(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS) + get_target_property(BUILT_LLCOMMON llcommon LOCATION) set_target_properties(llcommon @@ -1912,7 +1931,7 @@ if (WINDOWS) COMMENT "Copying Quicktime Plugin to the runtime folder." ) - get_target_property(BUILT_FILEPICKER_PLUGIN basic_plugin_filepicker LOCATION) + get_target_property(BUILT_FILEPICKER_PLUGIN basic_plugin_filepicker LOCATION) add_custom_command( TARGET ${VIEWER_BINARY_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} @@ -1924,7 +1943,9 @@ if (WINDOWS) COMMENT "Copying filepicker Plugin to the runtime folder." ) - get_target_property(BUILT_WINMM_SHIM_PLUGIN winmm_shim LOCATION) +# winmm doesn't build on windows 64 + if(WORD_SIZE EQUAL 32) + get_target_property(BUILT_WINMM_SHIM_PLUGIN winmm_shim LOCATION) add_custom_command( TARGET ${VIEWER_BINARY_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} @@ -1935,6 +1956,8 @@ if (WINDOWS) ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} COMMENT "Copying winmm.dll to the runtime folder." ) + endif(WORD_SIZE EQUAL 32) + # Copying the mime_types.xml file to app_settings set(mime_types_source "${CMAKE_SOURCE_DIR}/newview/skins/default/xui/en-us") set(mime_types_dest "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/app_settings") diff --git a/indra/newview/aixmllindengenepool.cpp b/indra/newview/aixmllindengenepool.cpp new file mode 100644 index 000000000..b02d4b60d --- /dev/null +++ b/indra/newview/aixmllindengenepool.cpp @@ -0,0 +1,205 @@ +/** + * @file aixmllindengenepool.cpp + * @brief XML linden_genepool serialization support. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 01/11/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +// metaversion 1.0 +// =============== +// +// Added as child of : +// +// +// +// Optionally, as child of , the following node may appear: +// +// +// +// Furthermore, metaversion 1.0 and higher allow the occurance of one or more blocks. +// If this is used then it is strongly advised to use one per wearable, so that +// the the node makes sense (it then refers to the wearable of that ). +// +// The reason for this clumsy way to link wearable to extra meta data is to stay +// compatible with the older format (no metaversion). + +#include "llviewerprecompiledheaders.h" +#include "aixmllindengenepool.h" +#include "hippogridmanager.h" +#include "llvisualparam.h" +#include "llviewerwearable.h" +#include "llquantize.h" + +extern void append_path_short(LLUUID const& id, std::string& path); + +void AIXMLLindenGenepool::MetaData::toXML(std::ostream& os, int indentation) const +{ + AIXMLElement tag(os, "meta", indentation); + tag.attribute("gridnick", mGridNick); + tag.attribute(DEFAULT_LLDATE_NAME, mDate); +} + +AIXMLLindenGenepool::MetaData::MetaData(AIXMLElementParser const& parser) +{ + parser.attribute("gridnick", mGridNick); + parser.attribute(DEFAULT_LLDATE_NAME, mDate); +} + +AIXMLLindenGenepool::AIXMLLindenGenepool(LLFILE* fp) : AIXMLRootElement(fp, "linden_genepool") +{ + attribute("version", "1.0"); + attribute("metaversion", "1.0"); + child(MetaData(gHippoGridManager->getConnectedGrid()->getGridNick(), LLDate::now())); +} + +void AIVisualParamIDValuePair::toXML(std::ostream& os, int indentation) const +{ + LLVisualParam const* visual_param = mVisualParam; + if (!visual_param && mWearable) + { + visual_param = mWearable->getVisualParam(mID); + } + if (visual_param) + { + AIXMLElement tag(os, "param", indentation); + tag.attribute("id", mID); + tag.attribute("name", visual_param->getName()); + tag.attribute("value", mValue); + tag.attribute("u8", (U32)F32_to_U8(mValue, visual_param->getMinWeight(), visual_param->getMaxWeight())); + tag.attribute("type", visual_param->getTypeString()); + tag.attribute("wearable", visual_param->getDumpWearableTypeName()); + } +} + +AIVisualParamIDValuePair::AIVisualParamIDValuePair(AIXMLElementParser const& parser) +{ + // Only id and value are relevant. Ignore all other attributes. + parser.attribute("id", mID); + parser.attribute("value", mValue); +} + +void AITextureIDUUIDPair::toXML(std::ostream& os, int indentation) const +{ + AIXMLElement tag(os, "texture", indentation); + tag.attribute("te", mID); + tag.attribute(DEFAULT_LLUUID_NAME, mUUID); +} + +AITextureIDUUIDPair::AITextureIDUUIDPair(AIXMLElementParser const& parser) +{ + parser.attribute("te", mID); + parser.attribute(DEFAULT_LLUUID_NAME, mUUID); +} + +void AIArchetype::MetaData::toXML(std::ostream& os, int indentation) const +{ + AIXMLElement tag(os, "meta", indentation); + tag.attribute("path", mPath); + tag.attribute("name", mName); + tag.attribute("description", mDescription); +} + +AIArchetype::MetaData::MetaData(AIXMLElementParser const& parser) +{ + char const* missing = NULL; + if (!parser.attribute("path", mPath)) + { + missing = "path"; + } + if (!parser.attribute("name", mName)) + { + missing = "name"; + } + if (!parser.attribute("description", mDescription)) + { + missing = "description"; + } + if (missing) + { + THROW_ALERT("AIArchetype_MetaData_archetype_meta_has_no_ATTRIBUTE", AIArgs("[ATTRIBUTE]", missing)); + } +} + +AIArchetype::MetaData::MetaData(LLViewerWearable const* wearable) : mName(wearable->getName()), mDescription(wearable->getDescription()) +{ + append_path_short(wearable->getItemID(), mPath); +} + +AIArchetype::AIArchetype(void) : mType(LLWearableType::WT_NONE) +{ +} + +AIArchetype::AIArchetype(LLWearableType::EType type) : mType(type) +{ +} + +AIArchetype::AIArchetype(LLViewerWearable const* wearable) : mType(wearable->getType()), mMetaData(wearable) +{ +} + +void AIArchetype::toXML(std::ostream& os, int indentation) const +{ + AIXMLElement tag(os, "archetype", indentation); + if (mType == LLWearableType::WT_NONE) + { + tag.attribute("name", "???"); + } + else + { + tag.attribute("name", LLWearableType::getTypeName(mType)); + } + if (!mMetaData.mPath.empty()) + { + tag.child(mMetaData); + } + tag.child(mParams.begin(), mParams.end()); + tag.child(mTextures.begin(), mTextures.end()); +} + +AIArchetype::AIArchetype(AIXMLElementParser const& parser) +{ + std::string name; + mType = LLWearableType::WT_NONE; + + if (!parser.attribute("name", name)) + { + llwarns << "The tag in file \"" << parser.filename() << "\" is missing the 'name' parameter." << llendl; + } + else if (name != "???") + { + mType = LLWearableType::typeNameToType(name); + } + if (parser.version() >= 1) + { + if (!parser.child("meta", mMetaData)) + { + THROW_ALERT("AIArchetype_archetype_has_no_meta"); + } + } + parser.push_back_children("param", mParams); + parser.push_back_children("texture", mTextures); +} + diff --git a/indra/newview/aixmllindengenepool.h b/indra/newview/aixmllindengenepool.h new file mode 100644 index 000000000..c3a5a65d6 --- /dev/null +++ b/indra/newview/aixmllindengenepool.h @@ -0,0 +1,150 @@ +/** + * @file aixmllindengenepool.h + * @brief XML linden_genepool serialization support. + * + * Copyright (c) 2013, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 01/11/2013 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AIXMLLINDENGENEPOOL_H +#define AIXMLLINDENGENEPOOL_H + +#include "aixml.h" +#include "llwearabletype.h" +#include "llviewervisualparam.h" +#include + +class LLViewerWearable; + +class AIXMLLindenGenepool : public AIXMLRootElement +{ + public: + struct MetaData + { + std::string mGridNick; + LLDate mDate; + + MetaData(void) { } + MetaData(std::string const& grid_nick, LLDate const& date) : mGridNick(grid_nick), mDate(date) { } + + void toXML(std::ostream& os, int indentation) const; + MetaData(AIXMLElementParser const& parser); + }; + + AIXMLLindenGenepool(LLFILE* fp); +}; + +class AIVisualParamIDValuePair +{ + private: + // A wearable + ID define the LLVisualParam, but it also possible to specify the LLVisualParam directly. + LLVisualParam const* mVisualParam; // Specific LLVisualParam, given at construction, or ... + LLViewerWearable const* mWearable; // Underlaying wearable, if any. + + U32 mID; // The visual parameter id. + F32 mValue; // The value of the visual parameter. + + public: + AIVisualParamIDValuePair(LLVisualParam const* visual_param) : + mVisualParam(visual_param), mWearable(NULL), mID(visual_param->getID()), mValue(visual_param->getWeight()) { } + + AIVisualParamIDValuePair(LLVisualParam const* visual_param, F32 value) : + mVisualParam(visual_param), mWearable(NULL), mID(visual_param->getID()), mValue(value) { } + + AIVisualParamIDValuePair(LLViewerWearable const* wearable, U32 id, F32 value) : + mVisualParam(NULL), mWearable(wearable), mID(id), mValue(value) { } + + void toXML(std::ostream& os, int indentation) const; + AIVisualParamIDValuePair(AIXMLElementParser const& parser); + + // Accessors. + U32 getID(void) const { return mID; } + F32 getValue(void) const { return mValue; } +}; + +class AITextureIDUUIDPair +{ + private: + U32 mID; + LLUUID mUUID; + + public: + AITextureIDUUIDPair(U32 id, LLUUID const& uuid) : mID(id), mUUID(uuid) { } + + void toXML(std::ostream& os, int indentation) const; + AITextureIDUUIDPair(AIXMLElementParser const& parser); + + // Accessors. + U32 getID(void) const { return mID; } + LLUUID const& getUUID(void) const { return mUUID; } +}; + +class AIArchetype +{ + public: + struct MetaData + { + std::string mPath; // The wearable location in the inventory. + std::string mName; // The wearable name. + std::string mDescription; // The wearable description. + + MetaData(void) { } + MetaData(LLViewerWearable const* wearable); + + void toXML(std::ostream& os, int indentation) const; + MetaData(AIXMLElementParser const& parser); + }; + + typedef std::vector params_type; + typedef std::vector textures_type; + + private: + LLWearableType::EType mType; // The type of the wearable. + MetaData mMetaData; + params_type mParams; + textures_type mTextures; + + public: + // Accessors. + LLWearableType::EType getType(void) const { return mType; } + MetaData const& getMetaData(void) const { return mMetaData; } + params_type const& getParams(void) const { return mParams; } + textures_type const& getTextures(void) const { return mTextures; } + + public: + // An archtype without wearable has no (known) metadata. This is recognized because mPath will be empty. + // An archtype without type with get the attribute name="???". + AIArchetype(void); // + AIArchetype(LLWearableType::EType type); // + AIArchetype(LLViewerWearable const* wearable); // + + void add(AIVisualParamIDValuePair const& visual_param_id_value_pair) { mParams.push_back(visual_param_id_value_pair); } + void add(AITextureIDUUIDPair const& texture_id_uuid_pair) { mTextures.push_back(texture_id_uuid_pair); } + + void toXML(std::ostream& os, int indentation) const; + AIArchetype(AIXMLElementParser const& parser); +}; + +#endif // AIXMLLINDENGENEPOOL_H diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index cbfda6de4..dcb34a4a6 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -40,7 +40,7 @@ tags - ShaderLoading + Openjpeg Plugin diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c1f005aba..54f0eef85 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8,7 +8,17 @@ settings_sh.xml settings_rlv.xml - + SinguOffsetScrollKeys + + Comment + Enable keys to modify camera and focus offsets + Persist + 1 + Type + Boolean + Value + 1 + PhoenixIMAnnounceStealFocus Comment @@ -210,17 +220,6 @@ 100 - zmm_deffov - - Comment - Default field of viewer for right click mouse zoom. - Persist - 1 - Type - F32 - Value - 1.0 - zmm_mlfov Comment @@ -232,28 +231,6 @@ Value 1 - zmm_isinml - - Comment - mouselook - Persist - 0 - Type - Boolean - Value - 0 - - zmm_rightmousedown - - Comment - insert rude comment here - Persist - 0 - Type - Boolean - Value - 0 - AllowLargeSounds @@ -786,6 +763,17 @@ Value 0 + LiruMouselookMenu + + Comment + Controls if holding Alt and right clicking in mouselook will bring up a menu + Persist + 1 + Type + Boolean + Value + 1 + LiruNewARCLimit Comment @@ -868,6 +856,17 @@ Found in Advanced->Rendering->Info Displays Value 0 + LiruUseContextMenus + + Comment + Use context menus instead of the default pie menus we all know and love. + Persist + 1 + Type + Boolean + Value + 0 + SLBShowFPS Comment @@ -936,6 +935,17 @@ Found in Advanced->Rendering->Info Displays Value 0 + FSSynchronizeTextureMaps + + Comment + Align texture maps (texture, bumpy, shiny) across the faces of a prim + Persist + 1 + Type + Boolean + Value + 1 + InstantMessageLogPathAnyAccount Comment @@ -5703,6 +5713,39 @@ This should be as low as possible, but too low may break functionality Value 0 + DefaultBlankNormalTexture + + Comment + Texture used as 'Blank' in texture picker for normal map. (UUID texture reference) + Persist + 1 + Type + String + Value + 5b53359e-59dd-d8a2-04c3-9e65134da47a + + DefaultObjectNormalTexture + + Comment + Texture used as 'Default' in texture picker for normal map. (UUID texture reference) + Persist + 1 + Type + String + Value + 85f28839-7a1c-b4e3-d71d-967792970a7b + + DefaultObjectSpecularTexture + + Comment + Texture used as 'Default' in texture picker for specular map. (UUID texture reference) + Persist + 1 + Type + String + Value + 87e0e8f7-8729-1ea8-cfc9-8915773009db + DefaultObjectTexture Comment @@ -13742,6 +13785,17 @@ This should be as low as possible, but too low may break functionality Value 1 + RevokePermsOnStopAnimation + + Comment + Clear animation permssions when choosing "Stop Animating Me" + Persist + 1 + Type + Boolean + Value + 1 + RotateRight Comment @@ -17735,7 +17789,7 @@ This should be as low as possible, but too low may break functionality Type S32 Value - 1 + 0 diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml index 4bd498e04..bc4537109 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -277,7 +277,7 @@ Type Boolean Value - 1 + 0 AscentShowOthersTagColor diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index cfc9d7c0d..35362cabb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #define INDEXED 1 #define NON_INDEXED 2 diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index c329bcde6..369a014fb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl index ccbc3c557..bf04caba5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl index a425e5062..9ddeae18d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl index ed02c4a48..848f52b9a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 58c18b4d9..167c2ae73 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl index edc6ff049..f351ec276 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl @@ -22,8 +22,6 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - - #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl index a2b4b3b8c..13409832a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl @@ -23,8 +23,8 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable -#extension GL_ARB_shader_texture_lod : enable +//#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; @@ -34,7 +34,7 @@ out vec4 frag_color; #define FXAA_PC 1 //#define FXAA_GLSL_130 1 -#define FXAA_QUALITY__PRESET 12 +#define FXAA_QUALITY_M_PRESET 12 /*============================================================================ @@ -67,7 +67,7 @@ Example, #define FXAA_PC 1 #define FXAA_HLSL_5 1 - #define FXAA_QUALITY__PRESET 12 + #define FXAA_QUALITY_M_PRESET 12 Or, @@ -366,7 +366,7 @@ A. Or use FXAA_GREEN_AS_LUMA. /*============================================================================ FXAA CONSOLE PS3 - TUNING KNOBS ============================================================================*/ -#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS +#ifndef FXAA_CONSOLE_M_PS3_EDGE_SHARPNESS // // Consoles the sharpness of edges on PS3 only. // Non-PS3 tuning is done with shader input. @@ -380,17 +380,17 @@ A. Or use FXAA_GREEN_AS_LUMA. // 2.0 is really soft (good for vector graphics inputs) // #if 1 - #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 + #define FXAA_CONSOLE_M_PS3_EDGE_SHARPNESS 8.0 #endif #if 0 - #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 + #define FXAA_CONSOLE_M_PS3_EDGE_SHARPNESS 4.0 #endif #if 0 - #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 + #define FXAA_CONSOLE_M_PS3_EDGE_SHARPNESS 2.0 #endif #endif /*--------------------------------------------------------------------------*/ -#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD +#ifndef FXAA_CONSOLE_M_PS3_EDGE_THRESHOLD // // Only effects PS3. // Non-PS3 tuning is done with shader input. @@ -408,9 +408,9 @@ A. Or use FXAA_GREEN_AS_LUMA. // 0.25 leaves more aliasing, and is sharper // #if 1 - #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 + #define FXAA_CONSOLE_M_PS3_EDGE_THRESHOLD 0.125 #else - #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 + #define FXAA_CONSOLE_M_PS3_EDGE_THRESHOLD 0.25 #endif #endif @@ -419,7 +419,7 @@ A. Or use FXAA_GREEN_AS_LUMA. ------------------------------------------------------------------------------ NOTE the other tuning knobs are now in the shader function inputs! ============================================================================*/ -#ifndef FXAA_QUALITY__PRESET +#ifndef FXAA_QUALITY_M_PRESET // // Choose the quality preset. // This needs to be compiled into the shader as it effects code. @@ -440,7 +440,7 @@ NOTE the other tuning knobs are now in the shader function inputs! // _ = the lowest digit is directly related to performance // _ = the highest digit is directly related to style // - #define FXAA_QUALITY__PRESET 12 + #define FXAA_QUALITY_M_PRESET 12 #endif @@ -453,198 +453,198 @@ NOTE the other tuning knobs are now in the shader function inputs! /*============================================================================ FXAA QUALITY - MEDIUM DITHER PRESETS ============================================================================*/ -#if (FXAA_QUALITY__PRESET == 10) - #define FXAA_QUALITY__PS 3 - #define FXAA_QUALITY__P0 1.5 - #define FXAA_QUALITY__P1 3.0 - #define FXAA_QUALITY__P2 12.0 +#if (FXAA_QUALITY_M_PRESET == 10) + #define FXAA_QUALITY_M_PS 3 + #define FXAA_QUALITY_M_P0 1.5 + #define FXAA_QUALITY_M_P1 3.0 + #define FXAA_QUALITY_M_P2 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 11) - #define FXAA_QUALITY__PS 4 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 3.0 - #define FXAA_QUALITY__P3 12.0 +#if (FXAA_QUALITY_M_PRESET == 11) + #define FXAA_QUALITY_M_PS 4 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 3.0 + #define FXAA_QUALITY_M_P3 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 12) - #define FXAA_QUALITY__PS 5 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 4.0 - #define FXAA_QUALITY__P4 12.0 +#if (FXAA_QUALITY_M_PRESET == 12) + #define FXAA_QUALITY_M_PS 5 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 4.0 + #define FXAA_QUALITY_M_P4 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 13) - #define FXAA_QUALITY__PS 6 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 4.0 - #define FXAA_QUALITY__P5 12.0 +#if (FXAA_QUALITY_M_PRESET == 13) + #define FXAA_QUALITY_M_PS 6 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 4.0 + #define FXAA_QUALITY_M_P5 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 14) - #define FXAA_QUALITY__PS 7 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 4.0 - #define FXAA_QUALITY__P6 12.0 +#if (FXAA_QUALITY_M_PRESET == 14) + #define FXAA_QUALITY_M_PS 7 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 4.0 + #define FXAA_QUALITY_M_P6 12.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 15) - #define FXAA_QUALITY__PS 8 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 4.0 - #define FXAA_QUALITY__P7 12.0 +#if (FXAA_QUALITY_M_PRESET == 15) + #define FXAA_QUALITY_M_PS 8 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 2.0 + #define FXAA_QUALITY_M_P6 4.0 + #define FXAA_QUALITY_M_P7 12.0 #endif /*============================================================================ FXAA QUALITY - LOW DITHER PRESETS ============================================================================*/ -#if (FXAA_QUALITY__PRESET == 20) - #define FXAA_QUALITY__PS 3 - #define FXAA_QUALITY__P0 1.5 - #define FXAA_QUALITY__P1 2.0 - #define FXAA_QUALITY__P2 8.0 +#if (FXAA_QUALITY_M_PRESET == 20) + #define FXAA_QUALITY_M_PS 3 + #define FXAA_QUALITY_M_P0 1.5 + #define FXAA_QUALITY_M_P1 2.0 + #define FXAA_QUALITY_M_P2 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 21) - #define FXAA_QUALITY__PS 4 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 8.0 +#if (FXAA_QUALITY_M_PRESET == 21) + #define FXAA_QUALITY_M_PS 4 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 22) - #define FXAA_QUALITY__PS 5 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 8.0 +#if (FXAA_QUALITY_M_PRESET == 22) + #define FXAA_QUALITY_M_PS 5 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 23) - #define FXAA_QUALITY__PS 6 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 8.0 +#if (FXAA_QUALITY_M_PRESET == 23) + #define FXAA_QUALITY_M_PS 6 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 24) - #define FXAA_QUALITY__PS 7 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 3.0 - #define FXAA_QUALITY__P6 8.0 +#if (FXAA_QUALITY_M_PRESET == 24) + #define FXAA_QUALITY_M_PS 7 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 3.0 + #define FXAA_QUALITY_M_P6 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 25) - #define FXAA_QUALITY__PS 8 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 4.0 - #define FXAA_QUALITY__P7 8.0 +#if (FXAA_QUALITY_M_PRESET == 25) + #define FXAA_QUALITY_M_PS 8 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 2.0 + #define FXAA_QUALITY_M_P6 4.0 + #define FXAA_QUALITY_M_P7 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 26) - #define FXAA_QUALITY__PS 9 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 4.0 - #define FXAA_QUALITY__P8 8.0 +#if (FXAA_QUALITY_M_PRESET == 26) + #define FXAA_QUALITY_M_PS 9 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 2.0 + #define FXAA_QUALITY_M_P6 2.0 + #define FXAA_QUALITY_M_P7 4.0 + #define FXAA_QUALITY_M_P8 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 27) - #define FXAA_QUALITY__PS 10 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 4.0 - #define FXAA_QUALITY__P9 8.0 +#if (FXAA_QUALITY_M_PRESET == 27) + #define FXAA_QUALITY_M_PS 10 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 2.0 + #define FXAA_QUALITY_M_P6 2.0 + #define FXAA_QUALITY_M_P7 2.0 + #define FXAA_QUALITY_M_P8 4.0 + #define FXAA_QUALITY_M_P9 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 28) - #define FXAA_QUALITY__PS 11 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 4.0 - #define FXAA_QUALITY__P10 8.0 +#if (FXAA_QUALITY_M_PRESET == 28) + #define FXAA_QUALITY_M_PS 11 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 2.0 + #define FXAA_QUALITY_M_P6 2.0 + #define FXAA_QUALITY_M_P7 2.0 + #define FXAA_QUALITY_M_P8 2.0 + #define FXAA_QUALITY_M_P9 4.0 + #define FXAA_QUALITY_M_P10 8.0 #endif /*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 29) - #define FXAA_QUALITY__PS 12 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 2.0 - #define FXAA_QUALITY__P10 4.0 - #define FXAA_QUALITY__P11 8.0 +#if (FXAA_QUALITY_M_PRESET == 29) + #define FXAA_QUALITY_M_PS 12 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.5 + #define FXAA_QUALITY_M_P2 2.0 + #define FXAA_QUALITY_M_P3 2.0 + #define FXAA_QUALITY_M_P4 2.0 + #define FXAA_QUALITY_M_P5 2.0 + #define FXAA_QUALITY_M_P6 2.0 + #define FXAA_QUALITY_M_P7 2.0 + #define FXAA_QUALITY_M_P8 2.0 + #define FXAA_QUALITY_M_P9 2.0 + #define FXAA_QUALITY_M_P10 4.0 + #define FXAA_QUALITY_M_P11 8.0 #endif /*============================================================================ FXAA QUALITY - EXTREME QUALITY ============================================================================*/ -#if (FXAA_QUALITY__PRESET == 39) - #define FXAA_QUALITY__PS 12 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.0 - #define FXAA_QUALITY__P2 1.0 - #define FXAA_QUALITY__P3 1.0 - #define FXAA_QUALITY__P4 1.0 - #define FXAA_QUALITY__P5 1.5 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 2.0 - #define FXAA_QUALITY__P10 4.0 - #define FXAA_QUALITY__P11 8.0 +#if (FXAA_QUALITY_M_PRESET == 39) + #define FXAA_QUALITY_M_PS 12 + #define FXAA_QUALITY_M_P0 1.0 + #define FXAA_QUALITY_M_P1 1.0 + #define FXAA_QUALITY_M_P2 1.0 + #define FXAA_QUALITY_M_P3 1.0 + #define FXAA_QUALITY_M_P4 1.0 + #define FXAA_QUALITY_M_P5 1.5 + #define FXAA_QUALITY_M_P6 2.0 + #define FXAA_QUALITY_M_P7 2.0 + #define FXAA_QUALITY_M_P8 2.0 + #define FXAA_QUALITY_M_P9 2.0 + #define FXAA_QUALITY_M_P10 4.0 + #define FXAA_QUALITY_M_P11 8.0 #endif @@ -869,7 +869,7 @@ FxaaFloat4 FxaaPixelShader( // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. // It is here now to allow easier tuning. // This does not effect PS3, as this needs to be compiled in. - // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Use FXAA_CONSOLE_M_PS3_EDGE_SHARPNESS for PS3. // Due to the PS3 being ALU bound, // there are only three safe values here: 2 and 4 and 8. // These options use the shaders ability to a free *|/ by 2|4|8. @@ -883,7 +883,7 @@ FxaaFloat4 FxaaPixelShader( // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. // It is here now to allow easier tuning. // This does not effect PS3, as this needs to be compiled in. - // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Use FXAA_CONSOLE_M_PS3_EDGE_THRESHOLD for PS3. // Due to the PS3 being ALU bound, // there are only two safe values here: 1/4 and 1/8. // These options use the shaders ability to a free *|/ by 2|4|8. @@ -1041,11 +1041,11 @@ FxaaFloat4 FxaaPixelShader( if( horzSpan) posB.y += lengthSign * 0.5; /*--------------------------------------------------------------------------*/ FxaaFloat2 posN; - posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; - posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + posN.x = posB.x - offNP.x * FXAA_QUALITY_M_P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY_M_P0; FxaaFloat2 posP; - posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; - posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + posP.x = posB.x + offNP.x * FXAA_QUALITY_M_P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY_M_P0; FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); FxaaFloat subpixE = subpixC * subpixC; @@ -1061,11 +1061,11 @@ FxaaFloat4 FxaaPixelShader( lumaEndP -= lumaNN * 0.5; FxaaBool doneN = abs(lumaEndN) >= gradientScaled; FxaaBool doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P1; FxaaBool doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P1; /*--------------------------------------------------------------------------*/ if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); @@ -1074,13 +1074,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P2; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P2; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 3) + #if (FXAA_QUALITY_M_PS > 3) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1088,13 +1088,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P3; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P3; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 4) + #if (FXAA_QUALITY_M_PS > 4) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1102,13 +1102,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P4; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P4; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 5) + #if (FXAA_QUALITY_M_PS > 5) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1116,13 +1116,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P5; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P5; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 6) + #if (FXAA_QUALITY_M_PS > 6) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1130,13 +1130,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P6; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P6; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 7) + #if (FXAA_QUALITY_M_PS > 7) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1144,13 +1144,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P7; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P7; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 8) + #if (FXAA_QUALITY_M_PS > 8) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1158,13 +1158,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P8; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P8; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 9) + #if (FXAA_QUALITY_M_PS > 9) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1172,13 +1172,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P9; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P9; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 10) + #if (FXAA_QUALITY_M_PS > 10) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1186,13 +1186,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P10; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P10; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 11) + #if (FXAA_QUALITY_M_PS > 11) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1200,13 +1200,13 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P11; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P11; /*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 12) + #if (FXAA_QUALITY_M_PS > 12) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); @@ -1214,11 +1214,11 @@ FxaaFloat4 FxaaPixelShader( if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_M_P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_M_P12; doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; + if(!doneP) posP.x += offNP.x * FXAA_QUALITY_M_P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY_M_P12; /*--------------------------------------------------------------------------*/ } #endif @@ -1291,9 +1291,9 @@ FxaaFloat4 FxaaPixelShader( ------------------------------------------------------------------------------ Instead of using this on PC, I'd suggest just using FXAA Quality with - #define FXAA_QUALITY__PRESET 10 + #define FXAA_QUALITY_M_PRESET 10 Or - #define FXAA_QUALITY__PRESET 20 + #define FXAA_QUALITY_M_PRESET 20 Either are higher qualilty and almost as fast as this on modern PC GPUs. ============================================================================*/ #if (FXAA_PC_CONSOLE == 1) @@ -1704,7 +1704,7 @@ half4 FxaaPixelShader( // (5) half4 dir1_pos; dir1_pos.xy = normalize(dir.xyz).xz; - half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); + half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE_M_PS3_EDGE_SHARPNESS); /*--------------------------------------------------------------------------*/ // (6) half4 dir2_pos; @@ -2019,7 +2019,7 @@ half4 FxaaPixelShader( // (6) half4 dir1_pos; dir1_pos.xy = normalize(dir).xz; - half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); + half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE_M_PS3_EDGE_SHARPNESS); /*--------------------------------------------------------------------------*/ // (7) half4 dir2_pos; @@ -2061,7 +2061,7 @@ half4 FxaaPixelShader( temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); half4 rgby2; rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; - half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; + half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE_M_PS3_EDGE_THRESHOLD; /*--------------------------------------------------------------------------*/ // (12) rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 236567219..d45d41f8e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 0e6ab80d4..2e01174e3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -31,8 +31,8 @@ out vec4 frag_color; //class 1 -- no shadows -#extension GL_ARB_texture_rectangle : enable -#extension GL_ARB_shader_texture_lod : enable +//#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_shader_texture_lod : enable uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; diff --git a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl index 62cfa5c31..1291cfe97 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 106d48bd7..4d6cfa487 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index bf362e21a..46ab281fd 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 126f17fab..690744352 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index eb5beeef3..b4e2ecfcc 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 430bad84a..7e149fae8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -23,8 +23,8 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable -#extension GL_ARB_shader_texture_lod : enable +//#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 8d8a6c9dd..f9fbca47f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -23,8 +23,8 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable -#extension GL_ARB_shader_texture_lod : enable +//#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index 5ca817aff..bc7837291 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -25,7 +25,7 @@ //class 1, no shadow, no SSAO, should never be called -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 730f01117..a1ae08bb6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -23,7 +23,7 @@ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 4b758772a..4f4d2cd6b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; diff --git a/indra/newview/app_settings/shaders/class1/effects/MotionBlurF.glsl b/indra/newview/app_settings/shaders/class1/effects/MotionBlurF.glsl index efa1265a1..f2b4900b4 100644 --- a/indra/newview/app_settings/shaders/class1/effects/MotionBlurF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/MotionBlurF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/effects/PosterizeF.glsl b/indra/newview/app_settings/shaders/class1/effects/PosterizeF.glsl index 0f8b2f8f2..fe983c258 100644 --- a/indra/newview/app_settings/shaders/class1/effects/PosterizeF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/PosterizeF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl b/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl index ad989e1a0..f3a6f4324 100644 --- a/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl b/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl index 6acd277bb..8a948b119 100644 --- a/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/effects/gaussBlurF.glsl b/indra/newview/app_settings/shaders/class1/effects/gaussBlurF.glsl index 6c56e2108..db12800a3 100644 --- a/indra/newview/app_settings/shaders/class1/effects/gaussBlurF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/gaussBlurF.glsl @@ -1,4 +1,4 @@ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl index 0f5eb288f..4f3690383 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl b/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl index 6257c4e9b..998d8eb18 100644 --- a/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl @@ -5,7 +5,7 @@ * $License$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl index 942c5888e..e7a59af2f 100644 --- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl index ed803de27..891b971f1 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl @@ -29,7 +29,7 @@ out vec4 frag_color; #define frag_color gl_FragColor #endif -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable uniform sampler2D glowMap; uniform sampler2DRect screenMap; diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl index 59520bb99..147de39c4 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl index 772bb374e..2e47c0023 100644 --- a/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index ac5b7d676..fdb10b151 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -23,8 +23,8 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable -#extension GL_ARB_shader_texture_lod : enable +//#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 08c235e2b..bcb66dc4c 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 7689b72d2..09881d9d7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -23,8 +23,8 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable -#extension GL_ARB_shader_texture_lod : enable +//#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_shader_texture_lod : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 0bdb21c31..043859894 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -23,7 +23,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 9616da637..2be812200 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -22,7 +22,7 @@ * $/LicenseInfo$ */ -#extension GL_ARB_texture_rectangle : enable +//#extension GL_ARB_texture_rectangle : enable #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index 5def0f4bb..d504a38fa 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -297,6 +297,7 @@ void LLPrefsAscentChat::refreshValues() mOneLineConfButt = gSavedSettings.getBOOL("UseConciseConferenceButtons"); mOnlyComm = gSavedSettings.getBOOL("CommunicateSpecificShortcut"); mItalicizeActions = gSavedSettings.getBOOL("LiruItalicizeActions"); + mLegacyLogLaunch = gSavedSettings.getBOOL("LiruLegacyLogLaunch"); mLegacySpeakerNames = gSavedSettings.getBOOL("LiruLegacySpeakerNames"); //Autoresponse ------------------------------------------------------------------------ @@ -535,6 +536,7 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setBOOL("UseConciseConferenceButtons", mOneLineConfButt); gSavedSettings.setBOOL("CommunicateSpecificShortcut", mOnlyComm); gSavedSettings.setBOOL("LiruItalicizeActions", mItalicizeActions); + gSavedSettings.setBOOL("LiruLegacyLogLaunch", mLegacyLogLaunch); gSavedSettings.setBOOL("LiruLegacySpeakerNames", mLegacySpeakerNames); //Autoresponse ------------------------------------------------------------------------ diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index 5e0ecd707..5b235dafa 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -38,13 +38,13 @@ class LLPrefsAscentChat : public LLPanel { public: - LLPrefsAscentChat(); - ~LLPrefsAscentChat(); + LLPrefsAscentChat(); + ~LLPrefsAscentChat(); - void apply(); - void cancel(); - void refresh(); - void refreshValues(); + void apply(); + void cancel(); + void refresh(); + void refreshValues(); protected: void onSpellAdd(); @@ -56,26 +56,27 @@ protected: void onCommitDialogBlock(LLUICtrl* ctrl, const LLSD& value); void onCommitKeywords(LLUICtrl* ctrl); - //Chat/IM ----------------------------------------------------------------------------- - BOOL mIMAnnounceIncoming; - BOOL mHideTypingNotification; - bool mInstantMessagesFriendsOnly; - BOOL mShowGroupNameInChatIM; - bool mShowDisplayNameChanges; - bool mUseTypingBubbles; - BOOL mPlayTypingSound; - BOOL mHideNotificationsInChat; - BOOL mEnableMUPose; - BOOL mEnableOOCAutoClose; - U32 mLinksForChattingObjects; - U32 mTimeFormat; - U32 mDateFormat; - U32 tempTimeFormat; - U32 tempDateFormat; - BOOL mSecondsInChatAndIMs; - BOOL mSecondsInLog; +private: + //Chat/IM ----------------------------------------------------------------------------- + bool mIMAnnounceIncoming; + bool mHideTypingNotification; + bool mInstantMessagesFriendsOnly; + bool mShowGroupNameInChatIM; + bool mShowDisplayNameChanges; + bool mUseTypingBubbles; + bool mPlayTypingSound; + bool mHideNotificationsInChat; + bool mEnableMUPose; + bool mEnableOOCAutoClose; + U32 mLinksForChattingObjects; + U32 mTimeFormat; + U32 mDateFormat; + U32 tempTimeFormat; + U32 tempDateFormat; + bool mSecondsInChatAndIMs; + bool mSecondsInLog; - //Chat UI ----------------------------------------------------------------------------- + //Chat UI ----------------------------------------------------------------------------- bool mWoLfVerticalIMTabs; bool mOtherChatsTornOff; bool mIMAnnounceStealFocus; @@ -87,6 +88,7 @@ protected: bool mOnlyComm; bool mItalicizeActions; bool mLegacySpeakerNames; + bool mLegacyLogLaunch; //Autoresponse ------------------------------------------------------------------------ std::string mIMResponseAnyoneItemID; @@ -94,39 +96,39 @@ protected: std::string mIMResponseMutedItemID; std::string mIMResponseBusyItemID; - //Spam -------------------------------------------------------------------------------- - BOOL mEnableAS; - BOOL mGlobalQueue; - U32 mChatSpamCount; - U32 mChatSpamTime; - BOOL mBlockDialogSpam; - BOOL mBlockAlertSpam; - BOOL mBlockFriendSpam; - BOOL mBlockGroupNoticeSpam; - BOOL mBlockGroupInviteSpam; - BOOL mBlockGroupFeeInviteSpam; - BOOL mBlockItemOfferSpam; + //Spam -------------------------------------------------------------------------------- + bool mEnableAS; + bool mGlobalQueue; + U32 mChatSpamCount; + U32 mChatSpamTime; + bool mBlockDialogSpam; + bool mBlockAlertSpam; + bool mBlockFriendSpam; + bool mBlockGroupNoticeSpam; + bool mBlockGroupInviteSpam; + bool mBlockGroupFeeInviteSpam; + bool mBlockItemOfferSpam; bool mBlockNotMineSpam; bool mBlockNotFriendSpam; - BOOL mBlockScriptSpam; - BOOL mBlockTeleportSpam; + bool mBlockScriptSpam; + bool mBlockTeleportSpam; bool mBlockTeleportRequestSpam; - BOOL mNotifyOnSpam; - BOOL mSoundMulti; - U32 mNewLines; - U32 mPreloadMulti; + bool mNotifyOnSpam; + bool mSoundMulti; + U32 mNewLines; + U32 mPreloadMulti; bool mEnableGestureSounds; - //Text Options ------------------------------------------------------------------------ - BOOL mSpellDisplay; - BOOL mKeywordsOn; - std::string mKeywordsList; - BOOL mKeywordsInChat; - BOOL mKeywordsInIM; - BOOL mKeywordsChangeColor; - LLColor4 mKeywordsColor; - BOOL mKeywordsPlaySound; - LLUUID mKeywordsSound; + //Text Options ------------------------------------------------------------------------ + bool mSpellDisplay; + bool mKeywordsOn; + std::string mKeywordsList; + bool mKeywordsInChat; + bool mKeywordsInIM; + bool mKeywordsChangeColor; + LLColor4 mKeywordsColor; + bool mKeywordsPlaySound; + LLUUID mKeywordsSound; }; #endif diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index 41e17241e..c287fea3e 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -222,6 +222,7 @@ void LLPrefsAscentSys::refreshValues() mEnableClassicClouds = gSavedSettings.getBOOL("SkyUseClassicClouds"); mSpeedRez = gSavedSettings.getBOOL("SpeedRez"); mSpeedRezInterval = gSavedSettings.getU32("SpeedRezInterval"); + mUseContextMenus = gSavedSettings.getBOOL("LiruUseContextMenus"); mUseWebProfiles = gSavedSettings.getBOOL("UseWebProfiles"); mUseWebSearch = gSavedSettings.getBOOL("UseWebSearch"); @@ -377,6 +378,7 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("SkyUseClassicClouds", mEnableClassicClouds); gSavedSettings.setBOOL("SpeedRez", mSpeedRez); gSavedSettings.setU32("SpeedRezInterval", mSpeedRezInterval); + gSavedSettings.setBOOL("LiruUseContextMenus", mUseContextMenus); gSavedSettings.setBOOL("UseWebProfiles", mUseWebProfiles); gSavedSettings.setBOOL("UseWebSearch", mUseWebSearch); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index 701a8e582..785d14940 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -38,13 +38,13 @@ class LLPrefsAscentSys : public LLPanel { public: - LLPrefsAscentSys(); - ~LLPrefsAscentSys(); + LLPrefsAscentSys(); + ~LLPrefsAscentSys(); - void apply(); - void cancel(); - void refresh(); - void refreshValues(); + void apply(); + void cancel(); + void refresh(); + void refreshValues(); protected: void onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value); @@ -52,61 +52,63 @@ protected: void onCommitComboBox(LLUICtrl* ctrl, const LLSD& value); void onCommitTexturePicker(LLUICtrl* ctrl); - //General ----------------------------------------------------------------------------- - BOOL mDoubleClickTeleport; - BOOL mResetCameraAfterTP; - BOOL mOffsetTPByUserHeight; - bool mClearBeaconAfterTeleport; - bool mLiruFlyAfterTeleport; - bool mLiruContinueFlying; - BOOL mPreviewAnimInWorld; - BOOL mSaveScriptsAsMono; - BOOL mAlwaysRezInGroup; - BOOL mBuildAlwaysEnabled; - BOOL mAlwaysShowFly; - BOOL mDisableMinZoom; - BOOL mPowerUser; - BOOL mFetchInventoryOnLogin; - BOOL mEnableLLWind; - BOOL mEnableClouds; - BOOL mEnableClassicClouds; - BOOL mSpeedRez; - U32 mSpeedRezInterval; +private: + //General ----------------------------------------------------------------------------- + bool mDoubleClickTeleport; + bool mResetCameraAfterTP; + bool mOffsetTPByUserHeight; + bool mClearBeaconAfterTeleport; + bool mLiruFlyAfterTeleport; + bool mLiruContinueFlying; + bool mPreviewAnimInWorld; + bool mSaveScriptsAsMono; + bool mAlwaysRezInGroup; + bool mBuildAlwaysEnabled; + bool mAlwaysShowFly; + bool mDisableMinZoom; + bool mPowerUser; + bool mFetchInventoryOnLogin; + bool mEnableLLWind; + bool mEnableClouds; + bool mEnableClassicClouds; + bool mSpeedRez; + U32 mSpeedRezInterval; + bool mUseContextMenus; bool mUseWebProfiles; bool mUseWebSearch; - //Command Line ------------------------------------------------------------------------ - BOOL mCmdLine; - std::string mCmdLinePos; - std::string mCmdLineGround; - std::string mCmdLineHeight; - std::string mCmdLineTeleportHome; - std::string mCmdLineRezPlatform; - F32 mCmdPlatformSize; - std::string mCmdLineCalc; - std::string mCmdLineClearChat; - std::string mCmdLineDrawDistance; - std::string mCmdTeleportToCam; - std::string mCmdLineKeyToName; - std::string mCmdLineOfferTp; - std::string mCmdLineMapTo; - BOOL mCmdMapToKeepPos; - std::string mCmdLineTP2; - std::string mCmdLineAway; + //Command Line ------------------------------------------------------------------------ + bool mCmdLine; + std::string mCmdLinePos; + std::string mCmdLineGround; + std::string mCmdLineHeight; + std::string mCmdLineTeleportHome; + std::string mCmdLineRezPlatform; + F32 mCmdPlatformSize; + std::string mCmdLineCalc; + std::string mCmdLineClearChat; + std::string mCmdLineDrawDistance; + std::string mCmdTeleportToCam; + std::string mCmdLineKeyToName; + std::string mCmdLineOfferTp; + std::string mCmdLineMapTo; + bool mCmdMapToKeepPos; + std::string mCmdLineTP2; + std::string mCmdLineAway; std::string mCmdLineURL; - //Security ---------------------------------------------------------------------------- - BOOL mBroadcastViewerEffects; - BOOL mDisablePointAtAndBeam; - BOOL mPrivateLookAt; - BOOL mShowLookAt; - BOOL mQuietSnapshotsToDisk; - BOOL mDetachBridge; - BOOL mRevokePermsOnStandUp; - BOOL mDisableClickSit; + //Security ---------------------------------------------------------------------------- + bool mBroadcastViewerEffects; + bool mDisablePointAtAndBeam; + bool mPrivateLookAt; + bool mShowLookAt; + bool mQuietSnapshotsToDisk; + bool mDetachBridge; + bool mRevokePermsOnStandUp; + bool mDisableClickSit; bool mDisableClickSitOtherOwner; - BOOL mDisplayScriptJumps; - F32 mNumScriptDiff; + bool mDisplayScriptJumps; + F32 mNumScriptDiff; //Build ------------------------------------------------------------------------------- F32 mAlpha; @@ -115,14 +117,14 @@ protected: F32 mGlow; std::string mItem; std::string mMaterial; - BOOL mNextCopy; - BOOL mNextMod; - BOOL mNextTrans; + bool mNextCopy; + bool mNextMod; + bool mNextTrans; std::string mShiny; - BOOL mTemporary; + bool mTemporary; std::string mTexture; - BOOL mPhantom; - BOOL mPhysical; + bool mPhantom; + bool mPhysical; F32 mXsize; F32 mYsize; F32 mZsize; diff --git a/indra/newview/ascentprefsvan.h b/indra/newview/ascentprefsvan.h index 77285b23d..edbe2cefb 100644 --- a/indra/newview/ascentprefsvan.h +++ b/indra/newview/ascentprefsvan.h @@ -38,24 +38,26 @@ class LLPrefsAscentVan : public LLPanel { public: - LLPrefsAscentVan(); - ~LLPrefsAscentVan(); + LLPrefsAscentVan(); + ~LLPrefsAscentVan(); - void apply(); - void cancel(); - void refresh(); - void refreshValues(); + void apply(); + void cancel(); + void refresh(); + void refreshValues(); protected: void onCommitClientTag(LLUICtrl* ctrl); void onCommitCheckBox(LLUICtrl* ctrl, const LLSD& value); void onCommitTextModified(LLUICtrl* ctrl, const LLSD& value); static void onManualClientUpdate(); - //Main - BOOL mUseAccountSettings; - BOOL mShowTPScreen; - BOOL mPlayTPSound; - BOOL mShowLogScreens; + +private: + //Main + bool mUseAccountSettings; + bool mShowTPScreen; + bool mPlayTPSound; + bool mShowLogScreens; bool mDisableChatAnimation; bool mAddNotReplace; bool mTurnAround; @@ -64,41 +66,38 @@ protected: bool mUnfocusedFloatersOpaque; bool mCompleteNameProfiles; bool mScriptErrorsStealFocus; - //Tags\Colors - BOOL mAscentBroadcastTag; - std::string mReportClientUUID; - U32 mSelectedClient; - BOOL mShowSelfClientTag; - BOOL mShowSelfClientTagColor; - BOOL mShowFriendsTag; - BOOL mDisplayClientTagOnNewLine; - BOOL mCustomTagOn; - std::string mCustomTagLabel; - LLColor4 mCustomTagColor; - BOOL mShowOthersTag; - BOOL mShowOthersTagColor; - BOOL mShowIdleTime; - BOOL mUseStatusColors; - BOOL mUpdateTagsOnLoad; - LLColor4 mEffectColor; - LLColor4 mFriendColor; - LLColor4 mEstateOwnerColor; - LLColor4 mLindenColor; - LLColor4 mMutedColor; + //Tags\Colors + bool mAscentBroadcastTag; + std::string mReportClientUUID; + U32 mSelectedClient; + bool mShowSelfClientTag; + bool mShowSelfClientTagColor; + bool mShowFriendsTag; + bool mDisplayClientTagOnNewLine; + bool mCustomTagOn; + std::string mCustomTagLabel; + LLColor4 mCustomTagColor; + bool mShowOthersTag; + bool mShowOthersTagColor; + bool mShowIdleTime; + bool mUseStatusColors; + bool mUpdateTagsOnLoad; + LLColor4 mEffectColor; + LLColor4 mFriendColor; + LLColor4 mEstateOwnerColor; + LLColor4 mLindenColor; + LLColor4 mMutedColor; LLColor4 mMapAvatarColor; LLColor4 mCustomColor; bool mColorFriendChat; bool mColorEOChat; bool mColorLindenChat; bool mColorMutedChat; -// bool mColorCustomChat; - - F32 mAvatarXModifier; - F32 mAvatarYModifier; - F32 mAvatarZModifier; - -private: + // bool mColorCustomChat; + F32 mAvatarXModifier; + F32 mAvatarYModifier; + F32 mAvatarZModifier; }; #endif diff --git a/indra/newview/awavefront.cpp b/indra/newview/awavefront.cpp index 4af106c12..ee83dbb3d 100644 --- a/indra/newview/awavefront.cpp +++ b/indra/newview/awavefront.cpp @@ -275,6 +275,13 @@ namespace { if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection()) { + if (!selection->getFirstRootObject()) + { + if (gSavedSettings.getBOOL("OBJExportNotifyFailed")) + LLNotificationsUtil::add("ExportFailed"); + return true; + } + WavefrontSaver* wfsaver = new WavefrontSaver; // deleted in callback wfsaver->offset = -selection->getFirstRootObject()->getRenderPosition(); S32 total = 0; diff --git a/indra/newview/daeexport.cpp b/indra/newview/daeexport.cpp index 8c8aa3641..7768aa541 100644 --- a/indra/newview/daeexport.cpp +++ b/indra/newview/daeexport.cpp @@ -272,7 +272,9 @@ public: void addSelectedObjects() { - if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection()) + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + + if (selection && selection->getFirstRootObject()) { mSaver.mOffset = -selection->getFirstRootObject()->getRenderPosition(); mObjectName = selection->getFirstRootNode()->mName; @@ -285,14 +287,15 @@ public: if (!node->getObject()->getVolume() || !DAEExportUtil::canExportNode(node)) continue; mSaver.add(node->getObject(), node->mName); } + } - if (mSaver.mObjects.empty()) - { - LLNotificationsUtil::add("ExportFailed"); - close(); - return; - } - + if (mSaver.mObjects.empty()) + { + LLNotificationsUtil::add("ExportFailed"); + close(); + } + else + { mSaver.updateTextureInfo(); mNumTextures = mSaver.mTextures.size(); mNumExportableTextures = getNumExportableTextures(); diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index bcc930a44..90b788f4f 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 27 +version 28 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -301,7 +301,7 @@ RenderObjectBump 0 0 list OpenGLPre15 RenderVBOEnable 1 0 -list Intel +list IntelPre30 RenderAnisotropic 1 0 // Avoid some Intel crashes on Linux RenderCubeMap 0 0 diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 7fa0e9531..af1a861ca 100644 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -301,7 +301,11 @@ Intel Eaglelake .*Intel.*Eaglelake.* 0 1 Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 0 1 Intel HD Graphics 2000 .*Intel.*HD Graphics 2000.* 1 1 Intel HD Graphics 3000 .*Intel.*HD Graphics 3000.* 2 1 +Intel HD Graphics 3000 .*Intel.*Sandybridge.* 2 1 Intel HD Graphics 4000 .*Intel.*HD Graphics 4000.* 2 1 +Intel HD Graphics 4000 .*Intel.*Ivybridge.* 2 1 +Intel HD Graphics 5000 .*Intel.*HD Graphics 5.* 2 1 +Intel HD Graphics 5000 .*Intel.*Haswell.* 2 1 Intel HD Graphics .*Intel.*HD Graphics.* 2 1 Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 @@ -312,6 +316,7 @@ Intel HD Graphics 2000 .*Intel.*HD2000.* 1 1 Intel HD Graphics 3000 .*Intel.*HD3000.* 2 1 Matrox .*Matrox.* 0 0 Mesa .*Mesa.* 0 0 +Gallium .*Gallium.* 1 1 NVIDIA 205 .*NVIDIA .*GeForce 205.* 2 1 NVIDIA 210 .*NVIDIA .*GeForce 210.* 2 1 NVIDIA 310M .*NVIDIA .*GeForce 310M.* 1 1 @@ -407,6 +412,12 @@ NVIDIA GTX 670 .*NVIDIA .*GTX *67.* 3 1 NVIDIA GTX 680M .*NVIDIA .*GTX *680M.* 3 1 NVIDIA GTX 680 .*NVIDIA .*GTX *68.* 3 1 NVIDIA GTX 690 .*NVIDIA .*GTX *69.* 3 1 +NVIDIA GTX 750 .*NVIDIA .*GTX *75.* 3 1 +NVIDIA GTX 760 .*NVIDIA .*GTX *76.* 3 1 +NVIDIA GTX 770 .*NVIDIA .*GTX *77.* 3 1 +NVIDIA GTX 780 .*NVIDIA .*GTX *78.* 3 1 +NVIDIA GTX TITAN .*NVIDIA .*GTX *TITAN.* 3 1 +NVIDIA GT 7xxM .*NVIDIA .*GT *7.* 3 1 NVIDIA C51 .*NVIDIA .*C51.* 0 1 NVIDIA G72 .*NVIDIA .*G72.* 1 1 NVIDIA G73 .*NVIDIA .*G73.* 1 1 diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 8fa0a943c..e78317e3f 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -35,6 +35,14 @@ RequestExecutionLevel admin ; on Vista we must be admin because we write to Prog %%GRID_VARS%% +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Alows us to determine if we're running on 64 bit OS; ${If} macros +!include "x64.nsh" +!include "LogicLib.nsh" + +;; are 64 bit binaries packaged in this installer +%%WIN64_BIN_BUILD%% + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; - language files - one for each language (or flavor thereof) ;; (these files are in the same place as the nsi template but the python script generates a new nsi file in the @@ -63,7 +71,7 @@ LangString LanguageCode ${LANG_DUTCH} "nl" LangString LanguageCode ${LANG_PORTUGUESEBR} "pt" LangString LanguageCode ${LANG_SIMPCHINESE} "zh" -Name ${VIEWERNAME} +Name "${VIEWERNAME}" SubCaption 0 $(LicenseSubTitleSetup) ; override "license agreement" text @@ -71,7 +79,7 @@ BrandingText "Prepare to Implode!" ; bottom of window text Icon %%SOURCE%%\installers\windows\install_icon_singularity.ico UninstallIcon %%SOURCE%%\installers\windows\uninstall_icon_singularity.ico WindowIcon off ; show our icon in left corner -BGGradient 9090b0 000000 notext +# BGGradient 9090b0 000000 notext CRCCheck on ; make sure CRC is OK #InstProgressFlags smooth colored ; new colored smooth look InstProgressFlags @@ -80,7 +88,7 @@ ShowInstDetails show ; no details, no "show" button SetOverwrite on ; stomp files by default AutoCloseWindow true ; after all files install, close window -InstallDir "$PROGRAMFILES\${INSTNAME}" +InstallDir "%%INSTALLDIR%%" InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "" DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup) @@ -664,6 +672,12 @@ FunctionEnd ;; entry to the language ID selector below ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function .onInit +!ifdef WIN64_BIN_BUILD + ${IfNot} ${RunningX64} + MessageBox MB_OK|MB_ICONSTOP "This version requires 64 bit operating sytem." + Quit + ${EndIf} +!endif Push $0 ${GetParameters} $COMMANDLINE ; get our command line ${GetOptions} $COMMANDLINE "/LANGID=" $0 ; /LANGID=1033 implies US English diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 6bd4acf33..9dd8caf36 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -77,7 +77,9 @@ fi export SDL_VIDEO_X11_DGAMOUSE=0 ## - Works around a problem with misconfigured 64-bit systems not finding GL -export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}":/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri +# This is less needed nowadays; don't uncomment this unless LibGL can't find your +# drivers automatically. +#export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}":/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri ## - The 'scim' GTK IM module widely crashes the viewer. Avoid it. if [ "$GTK_IM_MODULE" = "scim" ]; then diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d6188bcc0..081e3b65f 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -84,6 +84,7 @@ #include "llworld.h" #include "llworldmap.h" #include "llworldmapmessage.h" +#include "../lscript/lscript_byteformat.h" //Misc non-standard includes #include "llurldispatcher.h" @@ -3061,7 +3062,7 @@ LLQuaternion LLAgent::getHeadRotation() return rot; } -void LLAgent::sendAnimationRequests(LLDynamicArray &anim_ids, EAnimRequest request) +void LLAgent::sendAnimationRequests(const std::vector &anim_ids, EAnimRequest request) { if (gAgentID.isNull()) { @@ -3076,7 +3077,7 @@ void LLAgent::sendAnimationRequests(LLDynamicArray &anim_ids, EAnimReque msg->addUUIDFast(_PREHASH_AgentID, getID()); msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); - for (S32 i = 0; i < anim_ids.count(); i++) + for (U32 i = 0; i < anim_ids.size(); i++) { if (anim_ids[i].isNull()) { @@ -3118,6 +3119,55 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request) sendReliableMessage(); } +// Send a message to the region to stop the NULL animation state +// This will reset animation state overrides for the agent. +void LLAgent::sendAnimationStateReset() +{ + if (gAgentID.isNull() || !mRegionp) + { + return; + } + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_AgentAnimation); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, getID()); + msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + + msg->nextBlockFast(_PREHASH_AnimationList); + msg->addUUIDFast(_PREHASH_AnimID, LLUUID::null ); + msg->addBOOLFast(_PREHASH_StartAnim, FALSE); + + msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList); + msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0); + sendReliableMessage(); +} + + +// Send a message to the region to revoke sepecified permissions on ALL scripts in the region +// If the target is an object in the region, permissions in scripts on that object are cleared. +// If it is the region ID, all scripts clear the permissions for this agent +void LLAgent::sendRevokePermissions(const LLUUID & target, U32 permissions) +{ + // Currently only the bits for SCRIPT_PERMISSION_TRIGGER_ANIMATION and SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS + // are supported by the server. Sending any other bits will cause the message to be dropped without changing permissions + + if (gAgentID.notNull() && gMessageSystem) + { + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_RevokePermissions); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, getID()); // Must be our ID + msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + + msg->nextBlockFast(_PREHASH_Data); + msg->addUUIDFast(_PREHASH_ObjectID, target); // Must be in the region + msg->addU32Fast(_PREHASH_ObjectPermissions, permissions); + + sendReliableMessage(); + } +} + // [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i void LLAgent::setAlwaysRun() { @@ -4338,6 +4388,8 @@ void LLAgent::stopCurrentAnimations() // avatar, propagating this change back to the server. if (isAgentAvatarValid()) { + std::vector anim_ids; + for ( LLVOAvatar::AnimIterator anim_it = gAgentAvatarp->mPlayingAnimations.begin(); anim_it != gAgentAvatarp->mPlayingAnimations.end(); @@ -4355,7 +4407,24 @@ void LLAgent::stopCurrentAnimations() // stop this animation locally gAgentAvatarp->stopMotion(anim_it->first, TRUE); // ...and tell the server to tell everyone. - sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP); + anim_ids.push_back(anim_it->first); + } + } + + sendAnimationRequests(anim_ids, ANIM_REQUEST_STOP); + + // Tell the region to clear any animation state overrides + sendAnimationStateReset(); + + // Revoke all animation permissions + if (mRegionp && + gSavedSettings.getBOOL("RevokePermsOnStopAnimation")) + { + U32 permissions = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRIGGER_ANIMATION] | LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS]; + sendRevokePermissions(mRegionp->getRegionID(), permissions); + if (gAgentAvatarp->isSitting()) + { // Also stand up, since auto-granted sit animation permission has been revoked + gAgent.standUp(); } } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 8a01093bf..26501953a 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -464,8 +464,11 @@ public: void stopCurrentAnimations(); void requestStopMotion(LLMotion* motion); void onAnimStop(const LLUUID& id); - void sendAnimationRequests(LLDynamicArray &anim_ids, EAnimRequest request); + void sendAnimationRequests(const std::vector &anim_ids, EAnimRequest request); void sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request); + void sendAnimationStateReset(); + void sendRevokePermissions(const LLUUID & target, U32 permissions); + void endAnimationUpdateUI(); void unpauseAnimation() { mPauseRequest = NULL; } BOOL getCustomAnim() const { return mCustomAnim; } diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 05b3bd6df..5f979de31 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2022,6 +2022,22 @@ LLVector3 LLAgentCamera::getCameraOffsetInitial() return convert_from_llsd(mCameraOffsetInitial[mCameraPreset]->get(), TYPE_VEC3, ""); } +// Adds change to vector CachedControl, vec, at idx +template +void change_vec(const T& change, LLCachedControl& vec, const U32& idx = VZ) +{ + Vec changed(vec); + changed[idx] += change; + vec = changed; +} +// Same as above, but for ControlVariables +template +void change_vec(const T& change, LLPointer& vec, const U32& idx = VZ) +{ + Vec changed(vec->get()); + changed[idx] += change; + vec->set(changed.getValue()); +} //----------------------------------------------------------------------------- // handleScrollWheel() @@ -2057,6 +2073,23 @@ void LLAgentCamera::handleScrollWheel(S32 clicks) } else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON)) { + if (MASK mask = gKeyboard->currentMask(true)) // Singu Note: Conveniently set view offsets while modifier keys are held during scroll + { + static const LLCachedControl enableCameraOffsetScroll("SinguOffsetScrollKeys"); + if (mask & MASK_CONTROL|MASK_SHIFT && enableCameraOffsetScroll) + { + const F32 change(static_cast(clicks) * 0.1f); + if (mask & MASK_SHIFT) + { + change_vec(change, mFocusOffsetInitial[mCameraPreset]); + } + if (mask & MASK_CONTROL) + { + change_vec(change, mCameraOffsetInitial[mCameraPreset]); + } + return; + } + } F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec(); static const LLCachedControl camera_offset_scale("CameraOffsetScale"); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6be1d5c96..6449b376d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2625,7 +2625,11 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["ClientInfo"]["MinorVersion"] = gVersionMinor; gDebugInfo["ClientInfo"]["PatchVersion"] = gVersionPatch; gDebugInfo["ClientInfo"]["BuildVersion"] = gVersionBuild; - +#if defined(_WIN64) || defined(__x86_64__) + gDebugInfo["ClientInfo"]["Architecture"] = "x86_64"; +#else + gDebugInfo["ClientInfo"]["Architecture"] = "i386"; +#endif gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString(); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index a61f617c0..7d16a5340 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -53,6 +53,11 @@ #include "llviewercontrol.h" #include "lldxhardware.h" +#include "nvapi/nvapi.h" +#include "nvapi/NvApiDriverSettings.h" + +#include + #include "llweb.h" #include "llsecondlifeurls.h" @@ -80,6 +85,19 @@ extern "C" { const std::string LLAppViewerWin32::sWindowClass = "Second Life"; +/* + This function is used to print to the command line a text message + describing the nvapi error and quits +*/ +void nvapi_error(NvAPI_Status status) +{ + NvAPI_ShortString szDesc = {0}; + NvAPI_GetErrorMessage(status, szDesc); + llwarns << szDesc << llendl; + + //should always trigger when asserts are enabled + //llassert(status == NVAPI_OK); +} // Create app mutex creates a unique global windows object. // If the object can be created it returns true, otherwise @@ -102,6 +120,79 @@ bool create_app_mutex() return result; } +void ll_nvapi_init(NvDRSSessionHandle hSession) +{ + // (2) load all the system settings into the session + NvAPI_Status status = NvAPI_DRS_LoadSettings(hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + NvAPI_UnicodeString profile_name; + //std::string app_name = LLTrans::getString("APP_NAME"); + std::string app_name("Second Life"); // + llutf16string w_app_name = utf8str_to_utf16str(app_name); + wsprintf(profile_name, L"%s", w_app_name.c_str()); + status = NvAPI_DRS_SetCurrentGlobalProfile(hSession, profile_name); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + // (3) Obtain the current profile. + NvDRSProfileHandle hProfile = 0; + status = NvAPI_DRS_GetCurrentGlobalProfile(hSession, &hProfile); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + // load settings for querying + status = NvAPI_DRS_LoadSettings(hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + //get the preferred power management mode for Second Life + NVDRS_SETTING drsSetting = {0}; + drsSetting.version = NVDRS_SETTING_VER; + status = NvAPI_DRS_GetSetting(hSession, hProfile, PREFERRED_PSTATE_ID, &drsSetting); + if (status == NVAPI_SETTING_NOT_FOUND) + { //only override if the user hasn't specifically set this setting + // (4) Specify that we want the VSYNC disabled setting + // first we fill the NVDRS_SETTING struct, then we call the function + drsSetting.version = NVDRS_SETTING_VER; + drsSetting.settingId = PREFERRED_PSTATE_ID; + drsSetting.settingType = NVDRS_DWORD_TYPE; + drsSetting.u32CurrentValue = PREFERRED_PSTATE_PREFER_MAX; + status = NvAPI_DRS_SetSetting(hSession, hProfile, &drsSetting); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + + // (5) Now we apply (or save) our changes to the system + status = NvAPI_DRS_SaveSettings(hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } + } + else if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } +} + //#define DEBUGGING_SEH_FILTER 1 #if DEBUGGING_SEH_FILTER # define WINMAIN DebuggingWinMain @@ -158,6 +249,27 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, return -1; } + NvAPI_Status status; + + // Initialize NVAPI + status = NvAPI_Initialize(); + NvDRSSessionHandle hSession = 0; + + if (status == NVAPI_OK) + { + // Create the session handle to access driver settings + status = NvAPI_DRS_CreateSession(&hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + } + else + { + //override driver setting as needed + ll_nvapi_init(hSession); + } + } + // Have to wait until after logging is initialized to display LFH info if (num_heaps > 0) { @@ -225,6 +337,15 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, LLAppViewer::sUpdaterInfo = NULL ; } + + + // (NVAPI) (6) We clean up. This is analogous to doing a free() + if (hSession) + { + NvAPI_DRS_DestroySession(hSession); + hSession = 0; + } + return 0; } @@ -523,61 +644,7 @@ bool LLAppViewerWin32::restoreErrorTrap() void LLAppViewerWin32::initCrashReporting(bool reportFreeze) { - /* Singu Note: don't fork the crash logger on start - const char* logger_name = "win_crash_logger.exe"; - std::string exe_path = gDirUtilp->getExecutableDir(); - exe_path += gDirUtilp->getDirDelimiter(); - exe_path += logger_name; - - std::stringstream pid_str; - pid_str << LLApp::getPid(); - std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); - std::string appname = gDirUtilp->getExecutableFilename(); - - S32 slen = logdir.length() -1; - S32 end = slen; - while (logdir.at(end) == '/' || logdir.at(end) == '\\') end--; - - if (slen !=end) - { - logdir = logdir.substr(0,end+1); - } - std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str(); - llinfos << "spawning " << arg_str << llendl; - _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL); - */ - -/* STARTUPINFO siStartupInfo; - - std::string arg_str = "-dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + pid_str.str(); - - memset(&siStartupInfo, 0, sizeof(siStartupInfo)); - memset(&mCrashReporterProcessInfo, 0, sizeof(mCrashReporterProcessInfo)); - - siStartupInfo.cb = sizeof(siStartupInfo); - - std::wstring exe_wstr; - exe_wstr.assign(exe_path.begin(), exe_path.end()); - - std::wstring arg_wstr; - arg_wstr.assign(arg_str.begin(), arg_str.end()); - - if(CreateProcess(&exe_wstr[0], - &arg_wstr[0], // Application arguments - 0, - 0, - FALSE, - CREATE_DEFAULT_ERROR_MODE, - 0, - 0, // Working directory - &siStartupInfo, - &mCrashReporterProcessInfo) == FALSE) - // Could not start application -> call 'GetLastError()' - { - //llinfos << "CreateProcess failed " << GetLastError() << llendl; - return; - } - */ + // Singu Note: we don't fork the crash logger on start } //virtual diff --git a/indra/newview/llcrashlogger.cpp b/indra/newview/llcrashlogger.cpp index ad96ba19c..d79db0fae 100644 --- a/indra/newview/llcrashlogger.cpp +++ b/indra/newview/llcrashlogger.cpp @@ -40,7 +40,10 @@ #include "llhttpclient.h" #include "llsdserialize.h" #include "llproxy.h" +#include "llwindow.h" +#include "lltrans.h" #include "aistatemachine.h" +#include "boost/filesystem.hpp" class AIHTTPTimeoutPolicy; extern AIHTTPTimeoutPolicy crashLoggerResponder_timeout; @@ -144,6 +147,36 @@ std::string getStartupStateFromLog(std::string& sllog) return startup_state; } +bool miniDumpExists(const std::string& dumpDir) +{ + bool found = false; + + try + { + if (!boost::filesystem::exists(dumpDir)) + { + return false; + } + + boost::filesystem::directory_iterator end_itr; + for (boost::filesystem::directory_iterator i(dumpDir); i != end_itr; ++i) + { + if (!boost::filesystem::is_regular_file(i->status())) continue; + if (".dmp" == i->path().extension()) + { + found = true; + break; + } + } + } + catch (const boost::filesystem::filesystem_error& e) + { + llwarns << "Failed to determine existance of the minidump file: '" + e.code().message() +"'" << llendl; + } + + return found; +} + bool LLCrashLogger::readDebugFromXML(LLSD& dest, const std::string& filename ) { std::string db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,filename); @@ -350,20 +383,29 @@ bool LLCrashLogger::sendCrashLog(std::string dump_dir) void LLCrashLogger::checkCrashDump() { - mCrashHost = gSavedSettings.getString("CrashHostUrl"); - - std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug"; - if (gDirUtilp->fileExists(dumpDir)) - { #if LL_SEND_CRASH_REPORTS - if (!mCrashHost.empty() && gSavedSettings.getS32("CrashSubmitBehavior") != 2) + // 0 - ask, 1 - always send, 2 - never send + S32 pref = gSavedSettings.getS32("CrashSubmitBehavior"); + if (pref == 2) return; //never send + + mCrashHost = gSavedSettings.getString("CrashHostUrl"); + std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug"; + + // Do we have something to send, and somewhere to send it + if (!mCrashHost.empty() && miniDumpExists(dumpDir)) + { + if (pref == 1) // always send { sendCrashLog(dumpDir); } + else // ask + { + U32 response = OSMessageBox(LLTrans::getString("MBFrozenCrashed"), LLTrans::getString("MBAlert"), OSMB_YESNO); + if (response == OSBTN_YES) + { + sendCrashLog(dumpDir); + } + } + } #endif - } - else - { - llinfos << "No crash dump found frome previous run, not sending report" << LL_ENDL; - } } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index bf4907b8b..3e2dc4308 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -320,7 +320,7 @@ void LLDrawPoolAlpha::render(S32 pass) gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } - gGL.diffuseColor4f(1,0,0,1); + gGL.diffuseColor4f(0.9,0,0,0.4); LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f); gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 04d5f5115..77dc1e6c4 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1949,15 +1949,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector4a texIdx; - U8 index = mTextureIndex < 255 ? mTextureIndex : 0; + S32 index = mTextureIndex < 255 ? mTextureIndex : 0; F32 val = 0.f; - U8* vp = (U8*) &val; - vp[0] = index; - vp[1] = 0; - vp[2] = 0; - vp[3] = 0; - + S32* vp = (S32*) &val; + *vp = index; + llassert(index <= LLGLSLShader::sIndexedTextureChannels-1); LLVector4Logical mask; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 1551744bd..c3d0bc8a6 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -626,6 +626,10 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("GeForceFX"); } + if (gGLManager.mIsIntel && gGLManager.mGLVersion<3.0f) + { + maskFeatures("IntelPre30"); + } if (gGLManager.mIsIntel) { maskFeatures("Intel"); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 944335528..d47f5fb43 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -136,6 +136,9 @@ LLFloaterAbout::LLFloaterAbout() // Version string std::string version = std::string(LLAppViewer::instance()->getSecondLifeTitle() +#if defined(_WIN64) || defined(__x86_64__) + + " (64 bit)" +#endif + llformat(" %d.%d.%d (%d) %s %s (%s)\n", gVersionMajor, gVersionMinor, gVersionPatch, LL_VIEWER_BUILD, __DATE__, __TIME__, diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 4ce5e7c18..e6b8167ff 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -189,7 +189,17 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) using namespace boost::gregorian; int year, month, day; sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year); - mAge = (day_clock::local_day() - date(year, month, day)).days(); + try + { + mAge = (day_clock::local_day() - date(year, month, day)).days(); + } + catch(const std::exception&) + { + llwarns << "Failed to extract age from APT_PROPERTIES for " << mID << ", received \"" << pAvatarData->born_on << "\". Requesting properties again." << llendl; + LLAvatarPropertiesProcessor::getInstance()->addObserver(mID, this); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(mID); + return; + } if (!mStats[STAT_TYPE_AGE] && mAge >= 0) //Only announce age once per entry. { static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index 3a9e9f397..0df0663b9 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -53,8 +53,9 @@ #include "llvoavatarself.h" #include "statemachine/aifilepicker.h" -#include "llxmltree.h" #include "hippogridmanager.h" +#include "aixmllindengenepool.h" +#include "aifile.h" using namespace LLAvatarAppearanceDefines; @@ -330,215 +331,112 @@ void LLFloaterCustomize::onBtnImport_continued(AIFilePicker* filepicker) LLPanelEditWearable* panel_edit_wearable = getCurrentWearablePanel(); LLViewerWearable* edit_wearable = panel_edit_wearable->getWearable(); + LLWearableType::EType panel_wearable_type = panel_edit_wearable->getType(); + std::string label = utf8str_tolower(panel_edit_wearable->getLabel()); + std::string const filename = filepicker->getFilename(); - LLSD args(LLSD::emptyMap()); - args["FILE"] = gDirUtilp->getBaseFileName(filename); - LLXmlTree xml; - BOOL success = xml.parseFile(filename, FALSE); - if (!success) - { - LLNotificationsUtil::add("AIXMLImportParseError", args); - return; - } - LLXmlTreeNode* root = xml.getRoot(); - if (!root) - { - llwarns << "No root node found in wearable import file: " << filename << llendl; - LLNotificationsUtil::add("AIXMLImportParseError", args); - return; - } + AIArgs args("[FILE]", gDirUtilp->getBaseFileName(filename)); - //------------------------------------------------------------------------- - // (root) - //------------------------------------------------------------------------- - if (!root->hasName("linden_genepool")) - { - llwarns << "Invalid wearable import file (missing linden_genepool header): " << filename << llendl; - LLNotificationsUtil::add("AIXMLImportRootTypeError", args); - return; - } - static LLStdStringHandle const version_string = LLXmlTree::addAttributeString("version"); - std::string version; - if (!root->getFastAttributeString(version_string, version) || (version != "1.0")) - { - llwarns << "Invalid or incompatible linden_genepool version: " << version << " in file: " << filename << llendl; - args["TAG"] = "version"; - args["VERSIONMAJOR"] = "1"; - LLNotificationsUtil::add("AIXMLImportRootVersionError", args); - return; - } - static LLStdStringHandle const metaversion_string = LLXmlTree::addAttributeString("metaversion"); - std::string metaversion; - U32 metaversion_major; - if (!root->getFastAttributeString(metaversion_string, metaversion)) - { - llwarns << "Invalid linden_genepool metaversion: " << metaversion << " in file: " << filename << llendl; - metaversion_major = 0; - } - else if (!LLStringUtil::convertToU32(metaversion, metaversion_major) || metaversion_major > 1) - { - llwarns << "Invalid or incompatible linden_genepool metaversion: " << metaversion << " in file: " << filename << llendl; - args["TAG"] = "metaversion"; - args["VERSIONMAJOR"] = "1"; - LLNotificationsUtil::add("AIXMLImportRootVersionError", args); - return; - } - - //------------------------------------------------------------------------- - // - //------------------------------------------------------------------------- - std::string gridnick; - LLDate date; - bool different_grid = false; // By default assume it was exported on the same grid as we're on now. - bool mixed_grids = false; // Set to true if two different grids (might) share UUIDs. Currently only "secondlife" and "secondlife_beta". - if (metaversion_major >= 1) - { - static LLStdStringHandle const gridnick_string = LLXmlTree::addAttributeString("gridnick"); - static LLStdStringHandle const date_string = LLXmlTree::addAttributeString("date"); - std::string date_s; - bool invalid = true; - LLXmlTreeNode* meta_node = root->getChildByName("meta"); - if (!meta_node) - { - llwarns << "No meta (1) in wearable import file: " << filename << llendl; - } - else if (!meta_node->getFastAttributeString(gridnick_string, gridnick)) - { - llwarns << "meta tag in file: " << filename << " is missing the 'gridnick' parameter." << llendl; - } - else if (!meta_node->getFastAttributeString(date_string, date_s) || !date.fromString(date_s)) - { - llwarns << "meta tag in file: " << filename << " is missing or invalid 'date' parameter." << llendl; - } - else - { - invalid = false; - std::string current_gridnick = gHippoGridManager->getConnectedGrid()->getGridNick(); - different_grid = gridnick != current_gridnick; - mixed_grids = (gridnick == "secondlife" && current_gridnick == "secondlife_beta") || - (gridnick == "secondlife_beta" && current_gridnick == "secondlife"); - } - if (invalid) - { - LLNotificationsUtil::add("AIXMLImportInvalidError", args); - return; - } - } - - static LLStdStringHandle const name_string = LLXmlTree::addAttributeString("name"); - - //------------------------------------------------------------------------- - // - //------------------------------------------------------------------------- - LLXmlTreeNode* archetype_node = root->getChildByName("archetype"); - if (!archetype_node) - { - llwarns << "No archetype in wearable import file: " << filename << llendl; - LLNotificationsUtil::add("AIXMLImportInvalidError", args); - return; - } - // Legacy that name="" exists. Using it as human (only) readable type label of contents. Don't use it for anything else because it might not be set. - std::string label = "???"; - if (metaversion_major >= 1) - { - if (!archetype_node->getFastAttributeString(name_string, label)) - { - llwarns << "archetype tag in file: " << filename << " is missing the 'name' parameter." << llendl; - } - } - - //------------------------------------------------------------------------- - // - //------------------------------------------------------------------------- - std::string path; - std::string wearable_name; - std::string wearable_description; - if (metaversion_major >= 1) - { - static LLStdStringHandle const path_string = LLXmlTree::addAttributeString("path"); - static LLStdStringHandle const description_string = LLXmlTree::addAttributeString("description"); - bool invalid = true; - LLXmlTreeNode* meta_node = archetype_node->getChildByName("meta"); - if (!meta_node) - { - llwarns << "No meta (2) in wearable import file: " << filename << llendl; - } - else if (!meta_node->getFastAttributeString(path_string, path)) - { - llwarns << "meta tag in file: " << filename << " is missing the 'path' parameter." << llendl; - } - else if (!meta_node->getFastAttributeString(name_string, wearable_name)) - { - llwarns << "meta tag in file: " << filename << " is missing the 'name' parameter." << llendl; - } - else if (!meta_node->getFastAttributeString(description_string, wearable_description)) - { - llwarns << "meta tag in file: " << filename << " is missing the 'description' parameter." << llendl; - } - else - { - invalid = false; - } - if (invalid) - { - LLNotificationsUtil::add("AIXMLImportInvalidError", args); - return; - } - } - - // Parse the XML content. - static LLStdStringHandle const id_string = LLXmlTree::addAttributeString("id"); - static LLStdStringHandle const value_string = LLXmlTree::addAttributeString("value"); - static LLStdStringHandle const te_string = LLXmlTree::addAttributeString("te"); - static LLStdStringHandle const uuid_string = LLXmlTree::addAttributeString("uuid"); bool found_param = false; bool found_texture = false; - for(LLXmlTreeNode* child = archetype_node->getFirstChild(); child; child = archetype_node->getNextChild()) + bool found_type = false; + + bool different_grid = false; // By default assume it was exported on the same grid as we're on now. + bool mixed_grids = false; // Set to true if two different grids (might) share UUIDs. Currently only "secondlife" and "secondlife_beta". + std::string gridnick; + std::string wearable_types; + + try { - if (child->hasName("param")) + //------------------------------------------------------------------------- + // (root) + //------------------------------------------------------------------------- + std::string metaversion; + U32 metaversion_major; + + AIXMLParser linden_genepool(filename, "wearable import file", "linden_genepool", 1); + linden_genepool.attribute("version", "1.0"); + linden_genepool.attribute("metaversion", metaversion); + + if (!LLStringUtil::convertToU32(metaversion, metaversion_major) || metaversion_major > 1) { - std::string id_s; - U32 id; - std::string value_s; - F32 value; - if (!child->getFastAttributeString(id_string, id_s) || !LLStringUtil::convertToU32(id_s, id) || - !child->getFastAttributeString(value_string, value_s) || !LLStringUtil::convertToF32(value_s, value)) - { - llwarns << "Possible syntax error or corruption for node in " << filename << llendl; - continue; - } - LLVisualParam* visual_param = edit_wearable->getVisualParam(id); - if (visual_param) - { - found_param = true; - visual_param->setWeight(value, FALSE); - } + THROW_MALERT("AIXMLImportRootVersionError", args("[TAG]", "metaversion")("[VERSIONMAJOR]", "1")); } - else if (child->hasName("texture")) + + //------------------------------------------------------------------------- + // + //------------------------------------------------------------------------- + AIXMLLindenGenepool::MetaData meta_data; + + if (metaversion_major >= 1) { - std::string te_s; - S32 te; - std::string uuid_s; - LLUUID uuid; - if (!child->getFastAttributeString(te_string, te_s) || !LLStringUtil::convertToS32(te_s, te) || te < 0 || te >= TEX_NUM_INDICES || - !child->getFastAttributeString(uuid_string, uuid_s) || !uuid.set(uuid_s, TRUE)) + linden_genepool.child("meta", meta_data); + std::string current_gridnick = gHippoGridManager->getConnectedGrid()->getGridNick(); + gridnick = meta_data.mGridNick; + different_grid = gridnick != current_gridnick; + mixed_grids = (gridnick == "secondlife" && current_gridnick == "secondlife_beta") || + (gridnick == "secondlife_beta" && current_gridnick == "secondlife"); + } + + std::vector archetypes; + linden_genepool.setVersion(metaversion_major); + linden_genepool.push_back_children("archetype", archetypes); + + if (archetypes.empty()) + { + THROW_ALERT("AIXMLImportNoArchetypeError", AIArgs("[FILE]", filename)); + } + + for (std::vector::iterator archetype = archetypes.begin(); archetype != archetypes.end(); ++archetype) + { + LLWearableType::EType type = archetype->getType(); + if (type != LLWearableType::WT_NONE) { - llwarns << "Possible syntax error or corruption for node in " << filename << llendl; - continue; - } - ETextureIndex te_index = (ETextureIndex)te; - LLWearableType::EType te_wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(te_index); - if (te_wearable_type == edit_wearable->getType()) - { - found_texture = true; - if (!different_grid || mixed_grids) + if (!wearable_types.empty()) { - panel_edit_wearable->setNewImageID(te_index, uuid); + wearable_types += "/"; + } + wearable_types += LLWearableType::getTypeName(type); + if (panel_wearable_type == type) + { + found_type = true; + } + } + for (AIArchetype::params_type::const_iterator param = archetype->getParams().begin(); param != archetype->getParams().end(); ++param) + { + LLVisualParam* visual_param = edit_wearable->getVisualParam(param->getID()); + if (visual_param) + { + found_param = true; + visual_param->setWeight(param->getValue(), FALSE); + } + } + for (AIArchetype::textures_type::const_iterator texture = archetype->getTextures().begin(); texture != archetype->getTextures().end(); ++texture) + { + U32 te = texture->getID(); + if (te >= TEX_NUM_INDICES) + { + } + ETextureIndex te_index = (ETextureIndex)te; + LLWearableType::EType te_wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(te_index); + if (te_wearable_type == edit_wearable->getType()) + { + found_texture = true; + if (!different_grid || mixed_grids) + { + panel_edit_wearable->setNewImageID(te_index, texture->getUUID()); + } } } } } + catch (AIAlert::Error const& error) + { + AIAlert::add_modal("AIXMLImportError", AIArgs("[TYPE]", label), error); + return; + } + if (found_param || found_texture) { edit_wearable->writeToAvatar(gAgentAvatarp); @@ -546,23 +444,25 @@ void LLFloaterCustomize::onBtnImport_continued(AIFilePicker* filepicker) panel_edit_wearable->updateScrollingPanelUI(); if (found_texture && different_grid) { - args["EXPORTGRID"] = gridnick; - args["CURRENTGRID"] = gHippoGridManager->getConnectedGrid()->getGridNick(); + args("[EXPORTGRID]", gridnick); + args("[CURRENTGRID]", gHippoGridManager->getConnectedGrid()->getGridNick()); if (mixed_grids) { - LLNotificationsUtil::add("AIXMLImportMixedGrid", args); + AIAlert::add_modal("AIXMLImportMixedGrid", args); } else { - LLNotificationsUtil::add("AIXMLImportDifferentGrid", args); + AIAlert::add_modal("AIXMLImportDifferentGrid", args); } } } - else + else if (found_type) { - args["TYPE"] = panel_edit_wearable->LLPanel::getLabel(); - args["ARCHETYPENAME"] = label; - LLNotificationsUtil::add("AIXMLImportWearableTypeMismatch", args); + AIAlert::add("AIXMLImportEmptyArchetype", args("[TYPE]", label)); + } + else if (!wearable_types.empty()) + { + AIAlert::add("AIXMLImportWearableTypeMismatch", args("[TYPE]", label)("[ARCHETYPENAME]", wearable_types)); } } @@ -615,21 +515,26 @@ void LLFloaterCustomize::onBtnExport_continued(LLViewerWearable* edit_wearable, } std::string filename = filepicker->getFilename(); - LLSD args(LLSD::emptyMap()); - args["FILE"] = filename; - LLAPRFile outfile; - outfile.open(filename, LL_APR_WB); - if (!outfile.getFileHandle()) + bool success = false; + try { - llwarns << "Could not open \"" << filename << "\" for writing." << llendl; - LLNotificationsUtil::add("AIXMLExportWriteError", args); - return; + AIFile outfile(filename, "wb"); + + AIXMLLindenGenepool linden_genepool(outfile); + linden_genepool.child(edit_wearable->getArchetype()); + + success = true; + } + catch (AIAlert::Error const& error) + { + AIAlert::add_modal("AIXMLExportWriteError", AIArgs("[FILE]", filename), error); } - LLVOAvatar::dumpArchetypeXML_header(outfile, edit_wearable->getTypeName()); - edit_wearable->archetypeExport(outfile); - LLVOAvatar::dumpArchetypeXML_footer(outfile); + if (success) + { + AIAlert::add_modal("AIXMLExportSuccess", AIArgs("[FILE]", filename)); + } } void LLFloaterCustomize::onBtnOk() diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 448e1bb37..ba9233d65 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -89,7 +89,6 @@ LLFloaterInspect::~LLFloaterInspect(void) { gFloaterTools->setFocus(TRUE); } - //sInstance = NULL; } // static @@ -199,15 +198,6 @@ LLUUID LLFloaterInspect::getSelectedUUID() return LLUUID::null; } -void LLFloaterInspect::onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr) -{ - if (FloaterPtr) - { - LLFloaterInspect* floater = (LLFloaterInspect*)FloaterPtr; - floater->dirty(); - } -} - void LLFloaterInspect::refresh() { LLUUID creator_id; @@ -234,15 +224,14 @@ void LLFloaterInspect::refresh() { LLSelectNode* obj = *iter; LLSD row; - std::string owner_name, creator_name, time, last_owner_name; + std::string owner_name, creator_name, last_owner_name; if (obj->mCreationDate == 0) { // Don't have valid information from the server, so skip this one continue; } - time_t timestamp = (time_t) (obj->mCreationDate/1000000); - timeToFormattedString(timestamp, gSavedSettings.getString("TimestampFormat"), time); + // Singu Note: Diverge from LL and handle datetime column in a sortable manner later on const LLUUID& idOwner = obj->mPermissions->getOwner(); const LLUUID& idCreator = obj->mPermissions->getCreator(); @@ -266,7 +255,7 @@ void LLFloaterInspect::refresh() else { owner_name = LLTrans::getString("RetrievingData"); - LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this)); + LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::dirty, this)); } if (LLAvatarNameCache::get(idCreator, &av_name)) @@ -283,7 +272,7 @@ void LLFloaterInspect::refresh() else { creator_name = LLTrans::getString("RetrievingData"); - LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this)); + LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::dirty, this)); } // @@ -300,7 +289,7 @@ void LLFloaterInspect::refresh() else { last_owner_name = LLTrans::getString("RetrievingData"); - LLAvatarNameCache::get(idLastOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this)); + LLAvatarNameCache::get(idLastOwner, boost::bind(&LLFloaterInspect::dirty, this)); } // @@ -363,8 +352,10 @@ void LLFloaterInspect::refresh() row["columns"][7]["value"] = llformat("%d",total_inv); // row["columns"][8]["column"] = "creation_date"; - row["columns"][8]["type"] = "text"; - row["columns"][8]["value"] = time; + row["columns"][8]["type"] = "date"; + row["columns"][8]["value"] = LLDate(obj->mCreationDate/1000000); + static const LLCachedControl format("TimestampFormat"); + row["columns"][8]["format"] = format; mObjectList->addElement(row, ADD_TOP); } if(selected_index > -1 && mObjectList->getItemIndex(selected_uuid) == selected_index) diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h index 52e6a7f9a..f977f5403 100644 --- a/indra/newview/llfloaterinspect.h +++ b/indra/newview/llfloaterinspect.h @@ -63,8 +63,6 @@ public: void onClickOwnerProfile(); void onSelectObject(); - static void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr); - LLScrollListCtrl* mObjectList; protected: // protected members @@ -77,8 +75,6 @@ protected: private: LLFloaterInspect(); virtual ~LLFloaterInspect(void); - // static data -// static LLFloaterInspect* sInstance; LLSafeHandle mObjectSelection; // diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 3520b56e1..1902f115d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -726,8 +726,10 @@ void LLFloaterModelPreview::draw() } } + /* Singu Note: Dummy views and what for? childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost)); childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size())); + */ if (mModelPreview) { @@ -1155,7 +1157,7 @@ void LLFloaterModelPreview::initDecompControls() mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool); //llinfos << "Type: boolean, Default: " << (param[i].mDefault.mBool ? "True" : "False") << llendl; - LLCheckBoxCtrl* check_box = getChild(name); + LLCheckBoxCtrl* check_box = findChild(name); if (check_box) { check_box->setValue(param[i].mDefault.mBool); @@ -3710,7 +3712,6 @@ void LLModelPreview::loadModelCallback(S32 lod) mLoading = false; if (mFMP) { - mFMP->getChild("confirm_checkbox")->set(FALSE); if (!mBaseModel.empty()) { if (mFMP->getChild("description_form")->getValue().asString().empty()) @@ -4193,7 +4194,9 @@ void LLModelPreview::updateStatusMessages() } } + /* Singu Note: Dummy views and what for? mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH])); + */ std::string mesh_status_na = mFMP->getString("mesh_status_na"); @@ -5524,12 +5527,6 @@ void LLModelPreview::setPreviewLOD(S32 lod) combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order mFMP->childSetText("lod_file_" + lod_name[mPreviewLOD], mLODFile[mPreviewLOD]); - LLComboBox* combo_box2 = mFMP->getChild("preview_lod_combo2"); - combo_box2->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order - - LLComboBox* combo_box3 = mFMP->getChild("preview_lod_combo3"); - combo_box3->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order - LLColor4 highlight_color = LLUI::sColorsGroup->getColor("MeshImportTableHighlightColor"); LLColor4 normal_color = LLUI::sColorsGroup->getColor("MeshImportTableNormalColor"); diff --git a/indra/newview/llfloaterpathfindingobjects.cpp b/indra/newview/llfloaterpathfindingobjects.cpp index 8a606a07b..7fe3311cb 100644 --- a/indra/newview/llfloaterpathfindingobjects.cpp +++ b/indra/newview/llfloaterpathfindingobjects.cpp @@ -397,10 +397,9 @@ void LLFloaterPathfindingObjects::addObjectToScrollList(const LLPathfindingObjec } LLScrollListItem *scrollListItem = mObjectsScrollList->addElement(rowParams); - if (pObjectPtr->hasOwner() && !pObjectPtr->hasOwnerName()) { - mMissingNameObjectsScrollListItems.insert(std::make_pair(pObjectPtr->getUUID().asString(), scrollListItem)); + mMissingNameObjectsScrollListItems.insert(std::make_pair(pObjectPtr->getUUID().asString(), scrollListItem)); pObjectPtr->registerOwnerNameListener(boost::bind(&LLFloaterPathfindingObjects::handleObjectNameResponse, this, _1)); } } diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 99863e103..0cf47303f 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -527,7 +527,7 @@ void LLFloaterTools::refresh() { F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost(); LLStringUtil::format_map_t prim_equiv_args; - prim_equiv_args["SEL_WEIGHT"] = llformat("%.1d", (S32)link_cost); + prim_equiv_args["SEL_WEIGHT"] = llformat("%.0f", link_cost); selection_args["PE_STRING"] = getString("status_selectprimequiv", prim_equiv_args); } else diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index fec736819..3a6d2cbfb 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -111,6 +111,8 @@ public: void navigateToTitleMedia( const std::string url ); bool selectedMediaEditable(); + LLPanelFace* getPanelFace() { return mPanelFace; } + private: void refresh(); void refreshMedia(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3dd268d60..e41c1a3d1 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -5841,7 +5841,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } // [/RLVa:KB]*/ - bool not_modifiable = !gAgentWearables.isWearableModifiable(item->getUUID()); + bool not_modifiable = !item || !gAgentWearables.isWearableModifiable(item->getUUID()); if (((flags & FIRST_SELECTED_ITEM) == 0) || not_modifiable) { disabled_items.push_back(std::string("Wearable Edit")); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 55afaecee..80e68f608 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1414,7 +1414,10 @@ void LLMeshUploadThread::preStart() AIMeshUpload::AIMeshUpload(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, std::string const& upload_url, bool do_upload, LLHandle const& fee_observer, LLHandle const& upload_observer) : - mMeshUpload(new AIStateMachineThread), mWholeModelUploadURL(upload_url) +#ifdef CWDEBUG + AIStateMachine(false), +#endif + mMeshUpload(new AIStateMachineThread(CWD_ONLY(false))), mWholeModelUploadURL(upload_url) { mMeshUpload->thread_impl().init(data, scale, upload_textures, upload_skin, upload_joints, do_upload, fee_observer, upload_observer); } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 2c6e5a057..4dbb576c0 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -1839,12 +1839,9 @@ void LLPanelAvatar::sendAvatarPropertiesUpdate() { llinfos << "Sending avatarinfo update" << llendl; BOOL allow_publish = FALSE; - BOOL mature = FALSE; if (LLPanelAvatar::sAllowFirstLife) { allow_publish = childGetValue("allow_publish"); - //A profile should never be mature. - mature = FALSE; } LLUUID first_life_image_id; @@ -1867,7 +1864,6 @@ void LLPanelAvatar::sendAvatarPropertiesUpdate() avatar_data.about_text = about_text; avatar_data.fl_about_text = first_life_about_text; avatar_data.allow_publish = allow_publish; - //avatar_data.mature = mature; avatar_data.profile_url = mPanelWeb->childGetText("url_edit"); LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&avatar_data); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 78ae39dda..b211047bc 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -53,6 +53,7 @@ #include "llface.h" #include "llinventorymodel.h" //Perms check for texture params #include "lllineeditor.h" +#include "llmaterialmgr.h" #include "llmediaentry.h" #include "llnotificationsutil.h" #include "llresmgr.h" @@ -62,6 +63,7 @@ #include "lltexturectrl.h" #include "lltextureentry.h" #include "lltooldraganddrop.h" +#include "lltrans.h" #include "llui.h" #include "llviewercontrol.h" #include "llviewermedia.h" @@ -71,7 +73,62 @@ #include "llvovolume.h" #include "lluictrlfactory.h" #include "llpluginclassmedia.h" -#include "llviewertexturelist.h" +#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI + +// +// Constant definitions for comboboxes +// Must match the commbobox definitions in panel_tools_texture.xml +// +const S32 MATMEDIA_MATERIAL = 0; // Material +const S32 MATMEDIA_MEDIA = 1; // Media +const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture +const S32 MATTYPE_NORMAL = 1; // Normal map +const S32 MATTYPE_SPECULAR = 2; // Specular map +const S32 ALPHAMODE_NONE = 0; // No alpha mask applied +const S32 ALPHAMODE_BLEND = 1; // Alpha blending mode +const S32 ALPHAMODE_MASK = 2; // Alpha masking mode +const S32 BUMPY_TEXTURE = 18; // use supplied normal map +const S32 SHINY_TEXTURE = 4; // use supplied specular map + +// +// "Use texture" label for normal/specular type comboboxes +// Filled in at initialization from translated strings +// +std::string USE_TEXTURE; + +LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit() +{ + LLComboBox* combobox_matmedia = getChild("combobox matmedia"); + LLComboBox* combobox_mattype = getChild("combobox mattype"); + + LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? + (combobox_mattype ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP; + + channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; + channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; + return channel_to_edit; +} + +// Things the UI provides... +// +LLUUID LLPanelFace::getCurrentNormalMap() { return getChild("bumpytexture control")->getImageAssetID(); } +LLUUID LLPanelFace::getCurrentSpecularMap() { return getChild("shinytexture control")->getImageAssetID(); } +U32 LLPanelFace::getCurrentShininess() { return getChild("combobox shininess")->getCurrentIndex(); } +U32 LLPanelFace::getCurrentBumpiness() { return getChild("combobox bumpiness")->getCurrentIndex(); } +U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)getChild("combobox alphamode")->getCurrentIndex(); } +U8 LLPanelFace::getCurrentAlphaMaskCutoff() { return (U8)getChild("maskcutoff")->getValue().asInteger(); } +U8 LLPanelFace::getCurrentEnvIntensity() { return (U8)getChild("environment")->getValue().asInteger(); } +U8 LLPanelFace::getCurrentGlossiness() { return (U8)getChild("glossiness")->getValue().asInteger(); } +F32 LLPanelFace::getCurrentBumpyRot() { return getChild("bumpyRot")->getValue().asReal(); } +F32 LLPanelFace::getCurrentBumpyScaleU() { return getChild("bumpyScaleU")->getValue().asReal(); } +F32 LLPanelFace::getCurrentBumpyScaleV() { return getChild("bumpyScaleV")->getValue().asReal(); } +F32 LLPanelFace::getCurrentBumpyOffsetU() { return getChild("bumpyOffsetU")->getValue().asReal(); } +F32 LLPanelFace::getCurrentBumpyOffsetV() { return getChild("bumpyOffsetV")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyRot() { return getChild("shinyRot")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyScaleU() { return getChild("shinyScaleU")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyScaleV() { return getChild("shinyScaleV")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild("shinyOffsetU")->getValue().asReal(); } +F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild("shinyOffsetV")->getValue().asReal(); } // // Methods @@ -81,24 +138,46 @@ BOOL LLPanelFace::postBuild() { childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); - + childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this); childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("flipTextureScaleU", boost::bind(&LLPanelFace::onCommitFlip, this, true)); childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("flipTextureScaleV", boost::bind(&LLPanelFace::onCommitFlip, this, false)); childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this); - childSetAction("button apply",&LLPanelFace::onClickApply,this); + childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this); childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this); childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this); childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this); + + childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this); + childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this); + childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this); + childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this); + childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this); + childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this); + childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this); + childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this); + childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this); + childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this); + childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this); + childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this); + childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); + childSetAction("button align",&LLPanelFace::onClickAutoFix,this); + + childSetCommitCallback("checkbox maps sync", boost::bind(&LLPanelFace::onClickMapsSync, this)); childSetAction("copytextures",&LLPanelFace::onClickCopy,this); childSetAction("pastetextures",&LLPanelFace::onClickPaste,this); - + LLTextureCtrl* mTextureCtrl; + LLTextureCtrl* mShinyTextureCtrl; + LLTextureCtrl* mBumpyTextureCtrl; LLColorSwatchCtrl* mColorSwatch; + LLColorSwatchCtrl* mShinyColorSwatch; LLComboBox* mComboTexGen; + LLComboBox* mComboMatMedia; + LLComboBox* mComboMatType; LLCheckBoxCtrl *mCheckFullbright; @@ -108,6 +187,7 @@ BOOL LLPanelFace::postBuild() LLSpinCtrl* mCtrlGlow; setMouseOpaque(FALSE); + mTextureCtrl = getChild("texture control"); if(mTextureCtrl) { @@ -116,27 +196,48 @@ BOOL LLPanelFace::postBuild() mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) ); mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) ); mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); + mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); + mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); + mTextureCtrl->setFollowsTop(); mTextureCtrl->setFollowsLeft(); - // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode - mTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - // Allow any texture to be used during non-immediate mode. - mTextureCtrl->setNonImmediateFilterPermMask(PERM_NONE); - LLAggregatePermissions texture_perms; - if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms)) - { - BOOL can_copy = - texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || - texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL; - BOOL can_transfer = - texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || - texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL; - mTextureCtrl->setCanApplyImmediately(can_copy && can_transfer); - } - else - { - mTextureCtrl->setCanApplyImmediately(FALSE); - } + mTextureCtrl->setImmediateFilterPermMask(PERM_NONE); + mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + + mShinyTextureCtrl = getChild("shinytexture control"); + if(mShinyTextureCtrl) + { + mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" ))); + mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) ); + mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) ); + mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) ); + mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); + + mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); + mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); + mShinyTextureCtrl->setFollowsTop(); + mShinyTextureCtrl->setFollowsLeft(); + mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); + mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + + mBumpyTextureCtrl = getChild("bumpytexture control"); + if(mBumpyTextureCtrl) + { + mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" ))); + mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" ))); + mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) ); + mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) ); + mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) ); + mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) ); + + mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2)); + mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1)); + mBumpyTextureCtrl->setFollowsTop(); + mBumpyTextureCtrl->setFollowsLeft(); + mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE); + mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER); } mColorSwatch = getChild("colorswatch"); @@ -150,6 +251,15 @@ BOOL LLPanelFace::postBuild() mColorSwatch->setCanApplyImmediately(TRUE); } + mShinyColorSwatch = getChild("shinycolorswatch"); + if(mShinyColorSwatch) + { + mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2)); + mShinyColorSwatch->setFollowsTop(); + mShinyColorSwatch->setFollowsLeft(); + mShinyColorSwatch->setCanApplyImmediately(TRUE); + } + mLabelColorTransp = getChild("color trans"); if(mLabelColorTransp) { @@ -179,12 +289,26 @@ BOOL LLPanelFace::postBuild() mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); } + mComboMatMedia = getChild("combobox matmedia"); + if(mComboMatMedia) + { + mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this); + mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); + } + + mComboMatType = getChild("combobox mattype"); + if(mComboMatType) + { + mComboMatType->setCommitCallback(boost::bind(&LLPanelFace::onCommitMaterialType, this)); + mComboMatType->selectNthItem(MATTYPE_DIFFUSE); + } + mCtrlGlow = getChild("glow"); if(mCtrlGlow) { mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); } - + clearCtrls(); @@ -192,8 +316,10 @@ BOOL LLPanelFace::postBuild() } LLPanelFace::LLPanelFace(const std::string& name) -: LLPanel(name) +: LLPanel(name), + mIsAlpha(false) { + USE_TEXTURE = LLTrans::getString("use_texture"); } @@ -220,11 +346,31 @@ void LLPanelFace::sendTexture() } } -void LLPanelFace::sendBump() +void LLPanelFace::sendBump(U32 bumpiness) { - LLComboBox* mComboBumpiness = getChild("combobox bumpiness"); - if(!mComboBumpiness)return; - U8 bump = (U8) mComboBumpiness->getCurrentIndex() & TEM_BUMP_MASK; + LLTextureCtrl* bumpytexture_ctrl = getChild("bumpytexture control"); + if (bumpiness < BUMPY_TEXTURE) + { + LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL; + bumpytexture_ctrl->clear(); + bumpytexture_ctrl->setImageAssetID(LLUUID()); + } + + updateBumpyControls(bumpiness == BUMPY_TEXTURE, true); + + LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID(); + + U8 bump = (U8) bumpiness & TEM_BUMP_MASK; + + // Clear legacy bump to None when using an actual normal map + // + if (!current_normal_map.isNull()) + bump = 0; + + // Set the normal map or reset it to null as appropriate + // + LLSelectedTEMaterial::setNormalID(this, current_normal_map); + LLSelectMgr::getInstance()->selectionSetBumpmap( bump ); } @@ -236,12 +382,28 @@ void LLPanelFace::sendTexGen() LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen ); } -void LLPanelFace::sendShiny() +void LLPanelFace::sendShiny(U32 shininess) { - LLComboBox* mComboShininess = getChild("combobox shininess"); - if(!mComboShininess)return; - U8 shiny = (U8) mComboShininess->getCurrentIndex() & TEM_SHINY_MASK; + LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + + if (shininess < SHINY_TEXTURE) + { + texture_ctrl->clear(); + texture_ctrl->setImageAssetID(LLUUID()); + } + + LLUUID specmap = getCurrentSpecularMap(); + + U8 shiny = (U8) shininess & TEM_SHINY_MASK; + if (!specmap.isNull()) + shiny = 0; + + LLSelectedTEMaterial::setSpecularID(this, specmap); + LLSelectMgr::getInstance()->selectionSetShiny( shiny ); + + updateShinyControls(!specmap.isNull(), true); + } void LLPanelFace::sendFullbright() @@ -254,7 +416,6 @@ void LLPanelFace::sendFullbright() void LLPanelFace::sendColor() { - LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); if(!mColorSwatch)return; LLColor4 color = mColorSwatch->get(); @@ -274,7 +435,7 @@ void LLPanelFace::sendAlpha() void LLPanelFace::sendGlow() { - LLSpinCtrl* mCtrlGlow = getChild("glow"); + LLSpinCtrl* mCtrlGlow = getChild("glow"); llassert(mCtrlGlow); if (mCtrlGlow) { @@ -295,21 +456,16 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor LLSpinCtrl* ctrlTexOffsetS = mPanel->getChild("TexOffsetU"); LLSpinCtrl* ctrlTexOffsetT = mPanel->getChild("TexOffsetV"); LLSpinCtrl* ctrlTexRotation = mPanel->getChild("TexRot"); - LLCheckBoxCtrl* checkFlipScaleS = mPanel->getChild("checkbox flip s"); - LLCheckBoxCtrl* checkFlipScaleT = mPanel->getChild("checkbox flip t"); LLComboBox* comboTexGen = mPanel->getChild("combobox texgen"); llassert(comboTexGen); llassert(object); + if (ctrlTexScaleS) { - valid = !ctrlTexScaleS->getTentative() || !checkFlipScaleS->getTentative(); + valid = !ctrlTexScaleS->getTentative(); if (valid) { value = ctrlTexScaleS->get(); - if( checkFlipScaleS->get() ) - { - value = -value; - } if (comboTexGen && comboTexGen->getCurrentIndex() == 1) { @@ -321,14 +477,10 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor if (ctrlTexScaleT) { - valid = !ctrlTexScaleT->getTentative() || !checkFlipScaleT->getTentative(); + valid = !ctrlTexScaleT->getTentative(); if (valid) { value = ctrlTexScaleT->get(); - if( checkFlipScaleT->get() ) - { - value = -value; - } if (comboTexGen && comboTexGen->getCurrentIndex() == 1) { @@ -456,10 +608,10 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]); F32 st_rot = tep->getRotation(); // needs a fuzzy comparison, because of fp errors - if (is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 16) && - is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 16) && - is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 16) && - is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 16) && + if (is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12) && + is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12) && + is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 12) && + is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12) && is_approx_equal_fraction(st_rot, aligned_st_rot, 14)) { return true; @@ -484,16 +636,9 @@ void LLPanelFace::sendTextureInfo() { if ((bool)childGetValue("checkbox planar align").asBoolean()) { - struct f1 : public LLSelectedTEGetFunctor - { - LLFace* get(LLViewerObject* object, S32 te) - { - return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; - } - } get_last_face_func; - LLFace* last_face(NULL); - LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_face); - + LLFace* last_face = NULL; + bool identical_face = false; + LLSelectedTE::getFace(last_face, identical_face); LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face); LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); } @@ -509,8 +654,13 @@ void LLPanelFace::sendTextureInfo() void LLPanelFace::getState() { + updateUI(); +} + +void LLPanelFace::updateUI() +{ //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible) LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - LLCalc* calcp = LLCalc::getInstance(); + if( objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()) @@ -519,268 +669,74 @@ void LLPanelFace::getState() // only turn on auto-adjust button if there is a media renderer and the media is loaded getChildView("button align")->setEnabled(editable); - - //if ( LLMediaEngine::getInstance()->getMediaRenderer () ) - // if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) - // { - // - // //mLabelTexAutoFix->setEnabled ( editable ); - // - // //mBtnAutoFix->setEnabled ( editable ); - // } + + bool enable_material_controls = (!gSavedSettings.getBOOL("FSSynchronizeTextureMaps")); S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )) && (selected_count == 1); - childSetEnabled("copytextures", single_volume && editable); - childSetEnabled("pastetextures", single_volume && editable); - childSetEnabled("textbox params", single_volume && editable); - getChildView("button apply")->setEnabled(editable); + getChildView("copytextures")->setEnabled(single_volume && editable); + getChildView("pastetextures")->setEnabled(editable); + + LLComboBox* combobox_matmedia = getChild("combobox matmedia"); + if (combobox_matmedia) + { + if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL) + { + combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL); + } + } + else + { + LL_WARNS("Materials") << "failed getChild for 'combobox matmedia'" << LL_ENDL; + } + getChildView("combobox matmedia")->setEnabled(editable); + + LLComboBox* combobox_mattype = getChild("combobox mattype"); + if (combobox_mattype) + { + if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE) + { + combobox_mattype->selectNthItem(MATTYPE_DIFFUSE); + } + } + else + { + LL_WARNS("Materials") << "failed getChild for 'combobox mattype'" << LL_ENDL; + } + getChildView("combobox mattype")->setEnabled(editable); + + updateVisibility(); + + bool identical = true; // true because it is anded below + bool identical_diffuse = false; + bool identical_norm = false; + bool identical_spec = false; - bool identical; LLTextureCtrl* texture_ctrl = getChild("texture control"); texture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null. - // Texture - { - LLUUID id; - struct f1 : public LLSelectedTEGetFunctor - { - LLUUID get(LLViewerObject* object, S32 te_index) - { - LLUUID id; - //LLViewerTexture* image = object->getTEImage(te); - LLTextureEntry* image = object->getTE(te_index); //Singu Note: Use this instead of the above. - //The above actually returns LLViewerFetchedTexture::sDefaultImagep when - //the texture id is null, which gives us IMG_DEFAULT, not LLUUID::null - //Such behavior prevents the 'None' button from ever greying out in the face panel. - if (image) id = image->getID(); - - if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) - { - LLTextureEntry *te = object->getTE(te_index); - if (te) - { - LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ; - if(!tex) - { - tex = LLViewerFetchedTexture::sDefaultImagep; - } - if (tex) - { - id = tex->getID(); - } - } - } - return id; - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); + LLTextureCtrl* shinytexture_ctrl = getChild("shinytexture control"); + shinytexture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null. + LLTextureCtrl* bumpytexture_ctrl = getChild("bumpytexture control"); + bumpytexture_ctrl->setFallbackImageName( "" ); //Singu Note: Don't show the 'locked' image when the texid is null. - if(LLViewerMedia::textureHasMedia(id)) - { - getChildView("button align")->setEnabled(editable); - } - - if (identical) - { - // All selected have the same texture - if(texture_ctrl) - { - texture_ctrl->setTentative( FALSE ); - texture_ctrl->setEnabled( editable ); - texture_ctrl->setImageAssetID( id ); - } - } - else - { - if(texture_ctrl) - { - if( id.isNull() ) - { - // None selected - texture_ctrl->setTentative( FALSE ); - texture_ctrl->setEnabled( FALSE ); - texture_ctrl->setImageAssetID( LLUUID::null ); - } - else - { - // Tentative: multiple selected with different textures - texture_ctrl->setTentative( TRUE ); - texture_ctrl->setEnabled( editable ); - texture_ctrl->setImageAssetID( id ); - } - } - } - } - - - LLAggregatePermissions texture_perms; - if(texture_ctrl) - { -// texture_ctrl->setValid( editable ); - - if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms)) - { - BOOL can_copy = - texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || - texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL; - BOOL can_transfer = - texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || - texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL; - texture_ctrl->setCanApplyImmediately(can_copy && can_transfer); - } - else - { - texture_ctrl->setCanApplyImmediately(FALSE); - } - } - - - // planar align - bool align_planar = false; - bool identical_planar_aligned = false; - bool is_planar = false; - { - LLCheckBoxCtrl* cb_planar_align = getChild("checkbox planar align"); - align_planar = (cb_planar_align && cb_planar_align->get()); - struct f1 : public LLSelectedTEGetFunctor - { - bool get(LLViewerObject* object, S32 face) - { - return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR); - } - } func; - - bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar ); - bool enabled = (editable && texgens_identical && is_planar); - childSetValue("checkbox planar align", align_planar && enabled); - childSetEnabled("checkbox planar align", enabled); - - if (align_planar && enabled) - { - struct f2 : public LLSelectedTEGetFunctor - { - LLFace* get(LLViewerObject* object, S32 te) - { - return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; - } - } get_te_face_func; - LLFace* last_face(NULL); - LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_face); - LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face); - // this will determine if the texture param controls are tentative: - identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func); - } - } - - // Texture scale - { - getChildView("tex scale")->setEnabled(editable); - //mLabelTexScale->setEnabled( editable ); - F32 scale_s = 1.f; - struct f2 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return object->getTE(face)->mScaleS; - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s ); - identical = align_planar ? identical_planar_aligned : identical; - getChild("TexScaleU")->setValue(editable ? llabs(scale_s) : 0); - getChild("TexScaleU")->setTentative(LLSD((BOOL)(!identical))); - getChildView("TexScaleU")->setEnabled(editable); - getChild("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE ))); - getChild("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE ))); - getChildView("checkbox flip s")->setEnabled(editable); - } - - { - F32 scale_t = 1.f; - struct f3 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return object->getTE(face)->mScaleT; - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t ); - identical = align_planar ? identical_planar_aligned : identical; - - getChild("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0)); - getChild("TexScaleV")->setTentative(LLSD((BOOL)(!identical))); - getChildView("TexScaleV")->setEnabled(editable); - getChild("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE ))); - getChild("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE ))); - getChildView("checkbox flip t")->setEnabled(editable); - } - - // Texture offset - { - getChildView("tex offset")->setEnabled(editable); - F32 offset_s = 0.f; - struct f4 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return object->getTE(face)->mOffsetS; - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s ); - identical = align_planar ? identical_planar_aligned : identical; - getChild("TexOffsetU")->setValue(editable ? offset_s : 0); - getChild("TexOffsetU")->setTentative(!identical); - getChildView("TexOffsetU")->setEnabled(editable); - } - - { - F32 offset_t = 0.f; - struct f5 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return object->getTE(face)->mOffsetT; - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t ); - identical = align_planar ? identical_planar_aligned : identical; - getChild("TexOffsetV")->setValue(editable ? offset_t : 0); - getChild("TexOffsetV")->setTentative(!identical); - getChildView("TexOffsetV")->setEnabled(editable); - } - - // Texture rotation - { - getChildView("tex rotate")->setEnabled(editable); - F32 rotation = 0.f; - struct f6 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return object->getTE(face)->mRotation; - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation ); - identical = align_planar ? identical_planar_aligned : identical; - getChild("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0); - getChild("TexRot")->setTentative(!identical); - getChildView("TexRot")->setEnabled(editable); - } + LLUUID id; + LLUUID normmap_id; + LLUUID specmap_id; // Color swatch + { + getChildView("color label")->setEnabled(editable); + } LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); - LLColor4 color = LLColor4::white; + + LLColor4 color = LLColor4::white; + bool identical_color =false; + if(mColorSwatch) { - struct f7 : public LLSelectedTEGetFunctor - { - LLColor4 get(LLViewerObject* object, S32 face) - { - return object->getTE(face)->getColor(); - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, color ); - + LLSelectedTE::getColor(color, identical_color); + mColorSwatch->setOriginal(color); mColorSwatch->set(color, TRUE); @@ -788,176 +744,676 @@ void LLPanelFace::getState() mColorSwatch->setEnabled( editable ); mColorSwatch->setCanApplyImmediately( editable ); } + // Color transparency - { - getChildView("color trans")->setEnabled(editable); - } + getChildView("color trans")->setEnabled(editable); F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; + getChild("ColorTrans")->setValue(editable ? transparency : 0); + getChildView("ColorTrans")->setEnabled(editable); + + // Specular map + LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec); + + U8 shiny = 0; + bool identical_shiny = false; + + // Shiny + LLSelectedTE::getShiny(shiny, identical_shiny); + identical = identical && identical_shiny; + + shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE; + + LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess"); + if (combobox_shininess) { - getChild("ColorTrans")->setValue(editable ? transparency : 0); - getChildView("ColorTrans")->setEnabled(editable); + combobox_shininess->selectNthItem((S32)shiny); } + getChildView("label shininess")->setEnabled(editable); + getChildView("combobox shininess")->setEnabled(editable); + + getChildView("label glossiness")->setEnabled(editable); + getChildView("glossiness")->setEnabled(editable); + + getChildView("label environment")->setEnabled(editable); + getChildView("environment")->setEnabled(editable); + getChildView("label shinycolor")->setEnabled(editable); + + getChild("combobox shininess")->setTentative(!identical_spec); + getChild("glossiness")->setTentative(!identical_spec); + getChild("environment")->setTentative(!identical_spec); + getChild("shinycolorswatch")->setTentative(!identical_spec); + + LLColorSwatchCtrl* mShinyColorSwatch = getChild("shinycolorswatch"); + if(mShinyColorSwatch) { - F32 glow = 0.f; - struct f8 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return object->getTE(face)->getGlow(); - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow ); - - getChild("glow")->setValue(glow); - getChildView("glow")->setEnabled(editable); - getChild("glow")->setTentative(!identical); - getChildView("glow label")->setEnabled(editable); - + mShinyColorSwatch->setValid(editable); + mShinyColorSwatch->setEnabled( editable ); + mShinyColorSwatch->setCanApplyImmediately( editable ); } - // Bump + U8 bumpy = 0; + // Bumpy { - F32 shinyf = 0.f; - struct f9 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return (F32)(object->getTE(face)->getShiny()); - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shinyf ); - LLCtrlSelectionInterface* combobox_shininess = - childGetSelectionInterface("combobox shininess"); - if (combobox_shininess) - { - combobox_shininess->selectNthItem((S32)shinyf); - } - else - { - llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl; - } - getChildView("combobox shininess")->setEnabled(editable); - getChild("combobox shininess")->setTentative(!identical); - getChildView("label shininess")->setEnabled(editable); - } + bool identical_bumpy = false; + LLSelectedTE::getBumpmap(bumpy,identical_bumpy); + + LLUUID norm_map_id = getCurrentNormalMap(); + LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness"); + + bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE; - { - F32 bumpf = 0.f; - struct f10 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return (F32)(object->getTE(face)->getBumpmap()); - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpf ); - LLCtrlSelectionInterface* combobox_bumpiness = - childGetSelectionInterface("combobox bumpiness"); if (combobox_bumpiness) { - combobox_bumpiness->selectNthItem((S32)bumpf); + combobox_bumpiness->selectNthItem((S32)bumpy); } else { llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl; } + getChildView("combobox bumpiness")->setEnabled(editable); - getChild("combobox bumpiness")->setTentative(!identical); + getChild("combobox bumpiness")->setTentative(!identical_bumpy); getChildView("label bumpiness")->setEnabled(editable); } + // Texture { - F32 genf = 0.f; - struct f11 : public LLSelectedTEGetFunctor + LLSelectedTE::getTexId(id,identical_diffuse); + + // Normal map + LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm); + + mIsAlpha = FALSE; + LLGLenum image_format = GL_RGB; + bool identical_image_format = false; + LLSelectedTE::getImageFormat(image_format, identical_image_format); + + mIsAlpha = FALSE; + switch (image_format) { - F32 get(LLViewerObject* object, S32 face) + case GL_RGBA: + case GL_ALPHA: { - return (F32)(object->getTE(face)->getTexGen()); + mIsAlpha = TRUE; } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, genf ); - S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT; - LLCtrlSelectionInterface* combobox_texgen = - childGetSelectionInterface("combobox texgen"); + break; + + case GL_RGB: break; + default: + { + LL_WARNS("Materials") << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; + } + break; + } + + if(LLViewerMedia::textureHasMedia(id)) + { + getChildView("button align")->setEnabled(editable); + } + + // Diffuse Alpha Mode + + // Init to the default that is appropriate for the alpha content of the asset + // + U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + bool identical_alpha_mode = false; + + // See if that's been overridden by a material setting for same... + // + LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); + + LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode"); + if (combobox_alphamode) + { + //it is invalid to have any alpha mode other than blend if transparency is greater than zero ... + // Want masking? Want emissive? Tough! You get BLEND! + alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; + + // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none + alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + combobox_alphamode->selectNthItem(alpha_mode); + } + else + { + LL_WARNS("Materials") << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL; + } + + updateAlphaControls(); + + if (texture_ctrl) + { + if (identical_diffuse) + { + texture_ctrl->setTentative( FALSE ); + texture_ctrl->setEnabled( editable ); + texture_ctrl->setImageAssetID( id ); + getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); + getChildView("label alphamode")->setEnabled(editable && mIsAlpha); + getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); + getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + } + else if (id.isNull()) + { + // None selected + texture_ctrl->setTentative( FALSE ); + texture_ctrl->setEnabled( FALSE ); + texture_ctrl->setImageAssetID( LLUUID::null ); + getChildView("combobox alphamode")->setEnabled( FALSE ); + getChildView("label alphamode")->setEnabled( FALSE ); + getChildView("maskcutoff")->setEnabled( FALSE); + getChildView("label maskcutoff")->setEnabled( FALSE ); + } + else + { + // Tentative: multiple selected with different textures + texture_ctrl->setTentative( TRUE ); + texture_ctrl->setEnabled( editable ); + texture_ctrl->setImageAssetID( id ); + getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); + getChildView("label alphamode")->setEnabled(editable && mIsAlpha); + getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); + getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + } + } + + if (shinytexture_ctrl) + { + if (identical_spec && (shiny == SHINY_TEXTURE)) + { + shinytexture_ctrl->setTentative( FALSE ); + shinytexture_ctrl->setEnabled( editable ); + shinytexture_ctrl->setImageAssetID( specmap_id ); + } + else if (specmap_id.isNull()) + { + shinytexture_ctrl->setTentative( FALSE ); + shinytexture_ctrl->setEnabled( editable ); + shinytexture_ctrl->setImageAssetID( LLUUID::null ); + } + else + { + shinytexture_ctrl->setTentative( TRUE ); + shinytexture_ctrl->setEnabled( editable ); + shinytexture_ctrl->setImageAssetID( specmap_id ); + } + } + + if (bumpytexture_ctrl) + { + if (identical_norm && (bumpy == BUMPY_TEXTURE)) + { + bumpytexture_ctrl->setTentative( FALSE ); + bumpytexture_ctrl->setEnabled( editable ); + bumpytexture_ctrl->setImageAssetID( normmap_id ); + } + else if (normmap_id.isNull()) + { + bumpytexture_ctrl->setTentative( FALSE ); + bumpytexture_ctrl->setEnabled( editable ); + bumpytexture_ctrl->setImageAssetID( LLUUID::null ); + } + else + { + bumpytexture_ctrl->setTentative( TRUE ); + bumpytexture_ctrl->setEnabled( editable ); + bumpytexture_ctrl->setImageAssetID( normmap_id ); + } + } + } + + // planar align + bool align_planar = false; + bool identical_planar_aligned = false; + { + LLCheckBoxCtrl* cb_planar_align = getChild("checkbox planar align"); + align_planar = (cb_planar_align && cb_planar_align->get()); + + bool enabled = (editable && isIdenticalPlanarTexgen()); + childSetValue("checkbox planar align", align_planar && enabled); + childSetEnabled("checkbox planar align", enabled); + + if (align_planar && enabled) + { + LLFace* last_face = NULL; + bool identical_face = false; + LLSelectedTE::getFace(last_face, identical_face); + + LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face); + // this will determine if the texture param controls are tentative: + identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func); + } + } + + // Needs to be public and before tex scale settings below to properly reflect + // behavior when in planar vs default texgen modes in the + // NORSPEC-84 et al + // + LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; + bool identical_texgen = true; + bool identical_planar_texgen = false; + + { + LLSelectedTE::getTexGen(selected_texgen, identical_texgen); + identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); + } + + // Texture scale + { + bool identical_diff_scale_s = false; + bool identical_spec_scale_s = false; + bool identical_norm_scale_s = false; + + identical = align_planar ? identical_planar_aligned : identical; + + F32 diff_scale_s = 1.f; + F32 spec_scale_s = 1.f; + F32 norm_scale_s = 1.f; + + LLSelectedTE::getScaleS(diff_scale_s, identical_diff_scale_s); + LLSelectedTEMaterial::getSpecularRepeatX(spec_scale_s, identical_spec_scale_s); + LLSelectedTEMaterial::getNormalRepeatX(norm_scale_s, identical_norm_scale_s); + + diff_scale_s = editable ? diff_scale_s : 1.0f; + diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + + norm_scale_s = editable ? norm_scale_s : 1.0f; + norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + + spec_scale_s = editable ? spec_scale_s : 1.0f; + spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; + + getChild("TexScaleU")->setValue(diff_scale_s); + getChild("shinyScaleU")->setValue(spec_scale_s); + getChild("bumpyScaleU")->setValue(norm_scale_s); + + getChildView("TexScaleU")->setEnabled(editable); + getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull() + && enable_material_controls); // Materials alignment + getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull() + && enable_material_controls); // Materials alignment + + BOOL diff_scale_tentative = !(identical && identical_diff_scale_s); + BOOL norm_scale_tentative = !(identical && identical_norm_scale_s); + BOOL spec_scale_tentative = !(identical && identical_spec_scale_s); + + getChild("TexScaleU")->setTentative( LLSD(diff_scale_tentative)); + getChild("shinyScaleU")->setTentative(LLSD(spec_scale_tentative)); + getChild("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative)); + + // FIRE-11407 - Materials alignment + getChildView("checkbox maps sync")->setEnabled(editable && (specmap_id.notNull() || normmap_id.notNull())); + // + } + + { + bool identical_diff_scale_t = false; + bool identical_spec_scale_t = false; + bool identical_norm_scale_t = false; + + F32 diff_scale_t = 1.f; + F32 spec_scale_t = 1.f; + F32 norm_scale_t = 1.f; + + LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t); + LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t); + LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t); + + diff_scale_t = editable ? diff_scale_t : 1.0f; + diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + + norm_scale_t = editable ? norm_scale_t : 1.0f; + norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + + spec_scale_t = editable ? spec_scale_t : 1.0f; + spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f; + + BOOL diff_scale_tentative = !identical_diff_scale_t; + BOOL norm_scale_tentative = !identical_norm_scale_t; + BOOL spec_scale_tentative = !identical_spec_scale_t; + + getChildView("TexScaleV")->setEnabled(editable); + getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull() + && enable_material_controls); // Materials alignment + getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull() + && enable_material_controls); // Materials alignment + + getChild("TexScaleV")->setValue(diff_scale_t); + getChild("shinyScaleV")->setValue(norm_scale_t); + getChild("bumpyScaleV")->setValue(spec_scale_t); + + getChild("TexScaleV")->setTentative(LLSD(diff_scale_tentative)); + getChild("shinyScaleV")->setTentative(LLSD(norm_scale_tentative)); + getChild("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative)); + } + + // Texture offset + { + bool identical_diff_offset_s = false; + bool identical_norm_offset_s = false; + bool identical_spec_offset_s = false; + + F32 diff_offset_s = 0.0f; + F32 norm_offset_s = 0.0f; + F32 spec_offset_s = 0.0f; + + LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s); + LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s); + LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s); + + BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s); + BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s); + BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s); + + getChild("TexOffsetU")->setValue( editable ? diff_offset_s : 0.0f); + getChild("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f); + getChild("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f); + + getChild("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative)); + getChild("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative)); + getChild("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative)); + + getChildView("TexOffsetU")->setEnabled(editable); + getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull() + && enable_material_controls); // Materials alignment + getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull() + && enable_material_controls); // Materials alignment + } + + { + bool identical_diff_offset_t = false; + bool identical_norm_offset_t = false; + bool identical_spec_offset_t = false; + + F32 diff_offset_t = 0.0f; + F32 norm_offset_t = 0.0f; + F32 spec_offset_t = 0.0f; + + LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t); + LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t); + LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t); + + BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t); + BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t); + BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t); + + getChild("TexOffsetV")->setValue( editable ? diff_offset_t : 0.0f); + getChild("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f); + getChild("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f); + + getChild("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative)); + getChild("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative)); + getChild("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative)); + + getChildView("TexOffsetV")->setEnabled(editable); + getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull() + && enable_material_controls); // Materials alignment + getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull() + && enable_material_controls); // Materials alignment + } + + // Texture rotation + { + bool identical_diff_rotation = false; + bool identical_norm_rotation = false; + bool identical_spec_rotation = false; + + F32 diff_rotation = 0.f; + F32 norm_rotation = 0.f; + F32 spec_rotation = 0.f; + + LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation); + LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation); + LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation); + + BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation); + BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation); + BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation); + + F32 diff_rot_deg = diff_rotation * RAD_TO_DEG; + F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; + F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; + + getChildView("TexRot")->setEnabled(editable); + getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull() + && enable_material_controls); // Materials alignment + getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull() + && enable_material_controls); // Materials alignment + + getChild("TexRot")->setTentative(diff_rot_tentative); + getChild("shinyRot")->setTentative(LLSD(norm_rot_tentative)); + getChild("bumpyRot")->setTentative(LLSD(spec_rot_tentative)); + + getChild("TexRot")->setValue( editable ? diff_rot_deg : 0.0f); + getChild("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f); + getChild("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f); + } + + { + F32 glow = 0.f; + bool identical_glow = false; + LLSelectedTE::getGlow(glow,identical_glow); + getChild("glow")->setValue(glow); + getChild("glow")->setTentative(!identical_glow); + getChildView("glow")->setEnabled(editable); + getChildView("glow label")->setEnabled(editable); + } + + { + LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen"); if (combobox_texgen) { - combobox_texgen->selectNthItem(selected_texgen); + // Maps from enum to combobox entry index + combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1); } else { llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl; } + getChildView("combobox texgen")->setEnabled(editable); getChild("combobox texgen")->setTentative(!identical); getChildView("tex gen")->setEnabled(editable); - if (selected_texgen == 1) + if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR) { - getChild("TexScaleU")->setValue(2.0f * getChild("TexScaleU")->getValue().asReal() ); - getChild("TexScaleV")->setValue(2.0f * getChild("TexScaleV")->getValue().asReal() ); - // EXP-1507 (change label based on the mapping mode) - getChild("tex scale")->setValue(getString("string repeats per meter")); + getChild("rpt")->setValue(getString("string repeats per meter")); } else + if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT) { - getChild("tex scale")->setValue(getString("string repeats per face")); + getChild("rpt")->setValue(getString("string repeats per face")); } - } { - F32 fullbrightf = 0.f; - struct f12 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - return (F32)(object->getTE(face)->getFullbright()); - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf ); + U8 fullbright_flag = 0; + bool identical_fullbright = false; - getChild("checkbox fullbright")->setValue((S32)fullbrightf); + LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright); + + getChild("checkbox fullbright")->setValue((S32)(fullbright_flag != 0)); getChildView("checkbox fullbright")->setEnabled(editable); - getChild("checkbox fullbright")->setTentative(!identical); - } - - // Repeats per meter label - { - getChildView("rpt")->setEnabled(editable); + getChild("checkbox fullbright")->setTentative(!identical_fullbright); } + // Repeats per meter { - F32 repeats = 1.f; - struct f13 : public LLSelectedTEGetFunctor - { - F32 get(LLViewerObject* object, S32 face) - { - U32 s_axis = VX; - U32 t_axis = VY; - // BUG: Only repeats along S axis - // BUG: Only works for boxes. - LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); - return object->getTE(face)->mScaleS / object->getScale().mV[s_axis]; - } - } func; - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats ); - - getChild("rptctrl")->setValue(editable ? repeats : 0); - getChild("rptctrl")->setTentative(!identical); + F32 repeats_diff = 1.f; + F32 repeats_norm = 1.f; + F32 repeats_spec = 1.f; + + bool identical_diff_repeats = false; + bool identical_norm_repeats = false; + bool identical_spec_repeats = false; + + LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); + LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); + LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats); + LLComboBox* mComboTexGen = getChild("combobox texgen"); if (mComboTexGen) { - BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1); - getChildView("rptctrl")->setEnabled(enabled); - getChildView("button apply")->setEnabled(enabled); + S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; + BOOL enabled = editable && (index != 1); + BOOL identical_repeats = true; + F32 repeats = 1.0f; + + U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE; + + LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type)); + + switch (material_type) + { + default: + case MATTYPE_DIFFUSE: + { + enabled = editable && !id.isNull(); + identical_repeats = identical_diff_repeats; + repeats = repeats_diff; + } + break; + + case MATTYPE_SPECULAR: + { + enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()) + && enable_material_controls); // Materials Alignment + identical_repeats = identical_spec_repeats; + repeats = repeats_spec; + } + break; + + case MATTYPE_NORMAL: + { + enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()) + && enable_material_controls); // Materials Alignment + identical_repeats = identical_norm_repeats; + repeats = repeats_norm; + } + break; + } + + BOOL repeats_tentative = !identical_repeats; + + getChildView("rptctrl")->setEnabled(identical_planar_texgen ? FALSE : enabled); + getChild("rptctrl")->setValue(editable ? repeats : 1.0f); + getChild("rptctrl")->setTentative(LLSD(repeats_tentative)); + + // FIRE-11407 - Flip buttons + getChildView("flipTextureScaleU")->setEnabled(enabled); + getChildView("flipTextureScaleV")->setEnabled(enabled); + // + } + } + + // Materials + { + LLMaterialPtr material; + LLSelectedTEMaterial::getCurrent(material, identical); + + if (material && editable) + { + LL_DEBUGS("Materials: OnMatererialsLoaded:") << material->asLLSD() << LL_ENDL; + + // Alpha + LLCtrlSelectionInterface* combobox_alphamode = + childGetSelectionInterface("combobox alphamode"); + if (combobox_alphamode) + { + U32 alpha_mode = material->getDiffuseAlphaMode(); + + if (transparency > 0.f) + { //it is invalid to have any alpha mode other than blend if transparency is greater than zero ... + alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + } + + if (!mIsAlpha) + { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none + alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + } + + combobox_alphamode->selectNthItem(alpha_mode); + } + else + { + llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl; + } + getChild("maskcutoff")->setValue(material->getAlphaMaskCutoff()); + updateAlphaControls(); + + identical_planar_texgen = isIdenticalPlanarTexgen(); + + // Shiny (specular) + F32 offset_x, offset_y, repeat_x, repeat_y, rot; + LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + texture_ctrl->setImageAssetID(material->getSpecularID()); + + if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE)) + { + material->getSpecularOffset(offset_x,offset_y); + material->getSpecularRepeat(repeat_x,repeat_y); + + if (identical_planar_texgen) + { + repeat_x *= 2.0f; + repeat_y *= 2.0f; + } + + rot = material->getSpecularRotation(); + getChild("shinyScaleU")->setValue(repeat_x); + getChild("shinyScaleV")->setValue(repeat_y); + getChild("shinyRot")->setValue(rot*RAD_TO_DEG); + getChild("shinyOffsetU")->setValue(offset_x); + getChild("shinyOffsetV")->setValue(offset_y); + getChild("glossiness")->setValue(material->getSpecularLightExponent()); + getChild("environment")->setValue(material->getEnvironmentIntensity()); + + updateShinyControls(!material->getSpecularID().isNull(), true); + } + + // Assert desired colorswatch color to match material AFTER updateShinyControls + // to avoid getting overwritten with the default on some UI state changes. + // + if (!material->getSpecularID().isNull()) + { + getChild("shinycolorswatch")->setOriginal(material->getSpecularLightColor()); + getChild("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE); + } + + // Bumpy (normal) + texture_ctrl = getChild("bumpytexture control"); + texture_ctrl->setImageAssetID(material->getNormalID()); + + if (!material->getNormalID().isNull()) + { + material->getNormalOffset(offset_x,offset_y); + material->getNormalRepeat(repeat_x,repeat_y); + + if (identical_planar_texgen) + { + repeat_x *= 2.0f; + repeat_y *= 2.0f; + } + + rot = material->getNormalRotation(); + getChild("bumpyScaleU")->setValue(repeat_x); + getChild("bumpyScaleV")->setValue(repeat_y); + getChild("bumpyRot")->setValue(rot*RAD_TO_DEG); + getChild("bumpyOffsetU")->setValue(offset_x); + getChild("bumpyOffsetV")->setValue(offset_y); + + updateBumpyControls(!material->getNormalID().isNull(), true); + } } } // Set variable values for numeric expressions + LLCalc* calcp = LLCalc::getInstance(); calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal()); calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal()); @@ -976,7 +1432,6 @@ void LLPanelFace::getState() if(texture_ctrl) { texture_ctrl->setImageAssetID( LLUUID::null ); - texture_ctrl->setFallbackImageName( "locked_image.j2c" ); texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl. // texture_ctrl->setValid(FALSE); } @@ -989,32 +1444,32 @@ void LLPanelFace::getState() } getChildView("color trans")->setEnabled(FALSE); getChildView("rpt")->setEnabled(FALSE); - getChildView("tex scale")->setEnabled(FALSE); getChildView("tex offset")->setEnabled(FALSE); - getChildView("tex rotate")->setEnabled(FALSE); getChildView("tex gen")->setEnabled(FALSE); getChildView("label shininess")->setEnabled(FALSE); getChildView("label bumpiness")->setEnabled(FALSE); getChildView("button align")->setEnabled(FALSE); - getChildView("button apply")->setEnabled(FALSE); //getChildView("has media")->setEnabled(FALSE); //getChildView("media info set")->setEnabled(FALSE); + updateVisibility(); // Set variable values for numeric expressions + LLCalc* calcp = LLCalc::getInstance(); calcp->clearVar(LLCalc::TEX_U_SCALE); calcp->clearVar(LLCalc::TEX_V_SCALE); calcp->clearVar(LLCalc::TEX_U_OFFSET); calcp->clearVar(LLCalc::TEX_V_OFFSET); calcp->clearVar(LLCalc::TEX_ROTATION); calcp->clearVar(LLCalc::TEX_TRANSPARENCY); - calcp->clearVar(LLCalc::TEX_GLOW); + calcp->clearVar(LLCalc::TEX_GLOW); } } void LLPanelFace::refresh() { + LL_DEBUGS("Materials") << LL_ENDL; getState(); } @@ -1034,6 +1489,11 @@ void LLPanelFace::onCommitColor(const LLSD& data) sendColor(); } +void LLPanelFace::onCommitShinyColor(const LLSD& data) +{ + LLSelectedTEMaterial::setSpecularLightColor(this, getChild("shinycolorswatch")->get()); +} + void LLPanelFace::onCommitAlpha(const LLSD& data) { sendAlpha(); @@ -1050,11 +1510,124 @@ void LLPanelFace::onSelectColor(const LLSD& data) sendColor(); } +// static +void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + // Force to default states to side-step problems with menu contents + // and generally reflecting old state when switching tabs or objects + // + self->updateShinyControls(false,true); + self->updateBumpyControls(false,true); + self->updateUI(); +} + +// static +void LLPanelFace::updateVisibility() +{ + LLComboBox* combo_matmedia = getChild("combobox matmedia"); + LLComboBox* combo_mattype = getChild("combobox mattype"); + LLComboBox* combo_shininess = getChild("combobox shininess"); + LLComboBox* combo_bumpiness = getChild("combobox bumpiness"); + if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness) + { + LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL; + return; + } + U32 materials_media = combo_matmedia->getCurrentIndex(); + U32 material_type = combo_mattype->getCurrentIndex(); + bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); + bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled())); + bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled(); + bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); + getChildView("combobox mattype")->setVisible(!show_media); + // FIRE-11407 - Be consistant and hide this with the other controls + //getChildView("rptctrl")->setVisible(true); + getChildView("rptctrl")->setVisible(combo_matmedia->getEnabled()); + // and other additions... + getChildView("flipTextureScaleU")->setVisible(combo_matmedia->getEnabled()); + getChildView("flipTextureScaleV")->setVisible(combo_matmedia->getEnabled()); + // + + // Media controls + getChildView("media_info")->setVisible(show_media); + getChildView("add_media")->setVisible(show_media); + getChildView("delete_media")->setVisible(show_media); + getChildView("button align")->setVisible(show_media); + + // Diffuse texture controls + getChildView("texture control")->setVisible(show_texture && !show_media); + getChildView("label alphamode")->setVisible(show_texture && !show_media); + getChildView("combobox alphamode")->setVisible(show_texture && !show_media); + getChildView("label maskcutoff")->setVisible(false); + getChildView("maskcutoff")->setVisible(false); + if (show_texture && !show_media) + { + updateAlphaControls(); + } + getChildView("TexScaleU")->setVisible(show_texture); + getChildView("TexScaleV")->setVisible(show_texture); + getChildView("TexRot")->setVisible(show_texture); + getChildView("TexOffsetU")->setVisible(show_texture); + getChildView("TexOffsetV")->setVisible(show_texture); + + // Specular map controls + getChildView("shinytexture control")->setVisible(show_shininess); + getChildView("combobox shininess")->setVisible(show_shininess); + getChildView("label shininess")->setVisible(show_shininess); + getChildView("label glossiness")->setVisible(false); + getChildView("glossiness")->setVisible(false); + getChildView("label environment")->setVisible(false); + getChildView("environment")->setVisible(false); + getChildView("label shinycolor")->setVisible(false); + getChildView("shinycolorswatch")->setVisible(false); + if (show_shininess) + { + updateShinyControls(); + } + getChildView("shinyScaleU")->setVisible(show_shininess); + getChildView("shinyScaleV")->setVisible(show_shininess); + getChildView("shinyRot")->setVisible(show_shininess); + getChildView("shinyOffsetU")->setVisible(show_shininess); + getChildView("shinyOffsetV")->setVisible(show_shininess); + + // Normal map controls + if (show_bumpiness) + { + updateBumpyControls(); + } + getChildView("bumpytexture control")->setVisible(show_bumpiness); + getChildView("combobox bumpiness")->setVisible(show_bumpiness); + getChildView("label bumpiness")->setVisible(show_bumpiness); + getChildView("bumpyScaleU")->setVisible(show_bumpiness); + getChildView("bumpyScaleV")->setVisible(show_bumpiness); + getChildView("bumpyRot")->setVisible(show_bumpiness); + getChildView("bumpyOffsetU")->setVisible(show_bumpiness); + getChildView("bumpyOffsetV")->setVisible(show_bumpiness); +} + +void LLPanelFace::onCommitMaterialType() +{ + // Force to default states to side-step problems with menu contents + // and generally reflecting old state when switching tabs or objects + // + updateShinyControls(false,true); + updateBumpyControls(false,true); + updateUI(); +} + // static void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; - self->sendBump(); + + LLComboBox* mComboBumpiness = self->getChild("combobox bumpiness"); + if(!mComboBumpiness) + return; + + U32 bumpiness = mComboBumpiness->getCurrentIndex(); + + self->sendBump(bumpiness); } // static @@ -1064,11 +1637,142 @@ void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata) self->sendTexGen(); } +void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox) +{ + LLTextureCtrl* texture_ctrl = getChild("shinytexture control"); + LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID(); + LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL; + LLComboBox* comboShiny = getChild("combobox shininess"); + + if(mess_with_shiny_combobox) + { + if (!comboShiny) + { + return; + } + if (!shiny_texture_ID.isNull() && is_setting_texture) + { + if (!comboShiny->itemExists(USE_TEXTURE)) + { + comboShiny->add(USE_TEXTURE); + } + comboShiny->setSimple(USE_TEXTURE); + } + else + { + if (comboShiny->itemExists(USE_TEXTURE)) + { + comboShiny->remove(SHINY_TEXTURE); + comboShiny->selectFirstItem(); + } + } + } + + LLComboBox* combo_matmedia = getChild("combobox matmedia"); + LLComboBox* combo_mattype = getChild("combobox mattype"); + U32 materials_media = combo_matmedia->getCurrentIndex(); + U32 material_type = combo_mattype->getCurrentIndex(); + bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); + bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); + U32 shiny_value = comboShiny->getCurrentIndex(); + bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture + getChildView("label glossiness")->setVisible(show_shinyctrls); + getChildView("glossiness")->setVisible(show_shinyctrls); + getChildView("label environment")->setVisible(show_shinyctrls); + getChildView("environment")->setVisible(show_shinyctrls); + getChildView("label shinycolor")->setVisible(show_shinyctrls); + getChildView("shinycolorswatch")->setVisible(show_shinyctrls); +} + +void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox) +{ + LLTextureCtrl* texture_ctrl = getChild("bumpytexture control"); + LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); + LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; + LLComboBox* comboBumpy = getChild("combobox bumpiness"); + if (!comboBumpy) + { + return; + } + + if (mess_with_combobox) + { + LLTextureCtrl* texture_ctrl = getChild("bumpytexture control"); + LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID(); + LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL; + + if (!bumpy_texture_ID.isNull() && is_setting_texture) + { + if (!comboBumpy->itemExists(USE_TEXTURE)) + { + comboBumpy->add(USE_TEXTURE); + } + comboBumpy->setSimple(USE_TEXTURE); + } + else + { + if (comboBumpy->itemExists(USE_TEXTURE)) + { + comboBumpy->remove(BUMPY_TEXTURE); + comboBumpy->selectFirstItem(); + } + } + } +} + // static void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; - self->sendShiny(); + + + LLComboBox* mComboShininess = self->getChild("combobox shininess"); + if(!mComboShininess) + return; + + U32 shininess = mComboShininess->getCurrentIndex(); + + self->sendShiny(shininess); +} + +// static +void LLPanelFace::updateAlphaControls() +{ + LLComboBox* comboAlphaMode = getChild("combobox alphamode"); + if (!comboAlphaMode) + { + return; + } + U32 alpha_value = comboAlphaMode->getCurrentIndex(); + bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking + + LLComboBox* combobox_matmedia = getChild("combobox matmedia"); + U32 mat_media = MATMEDIA_MATERIAL; + if (combobox_matmedia) + { + mat_media = combobox_matmedia->getCurrentIndex(); + } + + LLComboBox* combobox_mattype = getChild("combobox mattype"); + U32 mat_type = MATTYPE_DIFFUSE; + if (combobox_mattype) + { + mat_type = combobox_mattype->getCurrentIndex(); + } + + show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL); + show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE); + + getChildView("label maskcutoff")->setVisible(show_alphactrls); + getChildView("maskcutoff")->setVisible(show_alphactrls); +} + +// static +void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + self->updateAlphaControls(); + LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode()); } // static @@ -1118,27 +1822,288 @@ void LLPanelFace::onSelectTexture(const LLSD& data) { LLSelectMgr::getInstance()->saveSelectedObjectTextures(); sendTexture(); + + LLGLenum image_format; + bool identical_image_format = false; + LLSelectedTE::getImageFormat(image_format, identical_image_format); + + LLCtrlSelectionInterface* combobox_alphamode = + childGetSelectionInterface("combobox alphamode"); + + U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + if (combobox_alphamode) + { + switch (image_format) + { + case GL_RGBA: + case GL_ALPHA: + { + alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + } + break; + + case GL_RGB: break; + default: + { + llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl; + } + break; + } + + combobox_alphamode->selectNthItem(alpha_mode); + } + LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode()); } +void LLPanelFace::onCloseTexturePicker(const LLSD& data) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + updateUI(); +} + +void LLPanelFace::onCommitSpecularTexture( const LLSD& data ) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + sendShiny(SHINY_TEXTURE); +} + +void LLPanelFace::onCommitNormalTexture( const LLSD& data ) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + LLUUID nmap_id = getCurrentNormalMap(); + sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); +} + +void LLPanelFace::onCancelSpecularTexture(const LLSD& data) +{ + U8 shiny = 0; + bool identical_shiny = false; + LLSelectedTE::getShiny(shiny, identical_shiny); + LLUUID spec_map_id = getChild("shinytexture control")->getImageAssetID(); + shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE; + sendShiny(shiny); +} + +void LLPanelFace::onCancelNormalTexture(const LLSD& data) +{ + U8 bumpy = 0; + bool identical_bumpy = false; + LLSelectedTE::getBumpmap(bumpy, identical_bumpy); + sendBump(bumpy); +} + +void LLPanelFace::onSelectSpecularTexture(const LLSD& data) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + sendShiny(SHINY_TEXTURE); +} + +void LLPanelFace::onSelectNormalTexture(const LLSD& data) +{ + LL_DEBUGS("Materials") << data << LL_ENDL; + LLUUID nmap_id = getCurrentNormalMap(); + sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); +} + +//static +void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU()); +} + +//static +void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV()); +} + +//static +void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU()); +} + +//static +void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV()); +} + +//static +void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + F32 bumpy_scale_u = self->getCurrentBumpyScaleU(); + if (self->isIdenticalPlanarTexgen()) + { + bumpy_scale_u *= 0.5f; + } + LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u); +} + +//static +void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + F32 bumpy_scale_v = self->getCurrentBumpyScaleV(); + if (self->isIdenticalPlanarTexgen()) + { + bumpy_scale_v *= 0.5f; + } + LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v); +} + +//static +void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + F32 shiny_scale_u = self->getCurrentShinyScaleU(); + if (self->isIdenticalPlanarTexgen()) + { + shiny_scale_u *= 0.5f; + } + LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u); +} + +//static +void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + F32 shiny_scale_v = self->getCurrentShinyScaleV(); + if (self->isIdenticalPlanarTexgen()) + { + shiny_scale_v *= 0.5f; + } + LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v); +} + +//static +void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD); +} + +//static +void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD); +} + +//static +void LLPanelFace::onCommitMaterialGloss(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness()); +} + +//static +void LLPanelFace::onCommitMaterialEnv(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + llassert_always(self); + LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity()); +} + +//static +void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff()); +} // static void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata ) { LLPanelFace* self = (LLPanelFace*) userdata; self->sendTextureInfo(); + // Materials alignment + if (gSavedSettings.getBOOL("FSSynchronizeTextureMaps")) + { + self->alignMaterialsProperties(); + } + // } // Commit the number of repeats per meter // static -void LLPanelFace::onClickApply(void* userdata) +void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; - gFocusMgr.setKeyboardFocus( NULL ); + LLUICtrl* repeats_ctrl = self->getChild("rptctrl"); + LLComboBox* combo_matmedia = self->getChild("combobox matmedia"); + LLComboBox* combo_mattype = self->getChild("combobox mattype"); - //F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get(); - F32 repeats_per_meter = (F32)self->getChild("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get(); - LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); + U32 materials_media = combo_matmedia->getCurrentIndex(); + + + U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? combo_mattype->getCurrentIndex() : 0; + F32 repeats_per_meter = repeats_ctrl->getValue().asReal(); + + F32 obj_scale_s = 1.0f; + F32 obj_scale_t = 1.0f; + + bool identical_scale_s = false; + bool identical_scale_t = false; + + LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); + LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); + + switch (material_type) + { + case MATTYPE_DIFFUSE: + { + LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); + } + break; + + case MATTYPE_NORMAL: + { + LLUICtrl* bumpy_scale_u = self->getChild("bumpyScaleU"); + LLUICtrl* bumpy_scale_v = self->getChild("bumpyScaleV"); + + bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); + bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); + + LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); + } + break; + + case MATTYPE_SPECULAR: + { + LLUICtrl* shiny_scale_u = self->getChild("shinyScaleU"); + LLUICtrl* shiny_scale_v = self->getChild("shinyScaleV"); + + shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); + shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); + + LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); + } + break; + + default: + llassert(false); + break; + } } struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor @@ -1210,6 +2175,267 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) self->sendTextureInfo(); } +void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp) +{ + LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL; + LLComboBox* combo_mattype = getChild("combobox mattype"); + if (!combo_mattype) + { + return; + } + U32 mattype = combo_mattype->getCurrentIndex(); + std::string which_control="texture control"; + switch (mattype) + { + case MATTYPE_SPECULAR: + which_control = "shinytexture control"; + break; + case MATTYPE_NORMAL: + which_control = "bumpytexture control"; + break; + // no default needed + } + LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL; + LLTextureCtrl* texture_ctrl = getChild(which_control); + if (texture_ctrl) + { + LLUUID obj_owner_id; + std::string obj_owner_name; + LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name); + + LLSaleInfo sale_info; + LLSelectMgr::instance().selectGetSaleInfo(sale_info); + + bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture? + bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture? + bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent? + bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale? + + if (can_copy && can_transfer) + { + texture_ctrl->setCanApply(true, true); + return; + } + + // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale + texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale); + + if (gSavedSettings.getBOOL("ApplyTextureImmediately")) + { + LLNotificationsUtil::add("LivePreviewUnavailable"); + } + } +} + +bool LLPanelFace::isIdenticalPlanarTexgen() +{ + LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT; + bool identical_texgen = false; + LLSelectedTE::getTexGen(selected_texgen, identical_texgen); + return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)); +} + +void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face) +{ + struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor + { + LLFace* get(LLViewerObject* object, S32 te) + { + return (object->mDrawable) ? object->mDrawable->getFace(te): NULL; + } + } get_te_face_func; + identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return); +} + +void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face) +{ + LLGLenum image_format; + struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor + { + LLGLenum get(LLViewerObject* object, S32 te_index) + { + LLViewerTexture* image = object->getTEImage(te_index); + return image ? image->getPrimaryFormat() : GL_RGB; + } + } get_glenum; + identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format); + image_format_to_return = image_format; +} + +void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) +{ + struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor + { + LLUUID get(LLViewerObject* object, S32 te_index) + { + LLUUID id; + LLViewerTexture* image = object->getTEImage(te_index); + if (image) + { + id = image->getID(); + } + + if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) + { + LLTextureEntry *te = object->getTE(te_index); + if (te) + { + LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL; + if(!tex) + { + tex = LLViewerFetchedTexture::sDefaultImagep; + } + if (tex) + { + id = tex->getID(); + } + } + } + return id; + } + } func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id ); +} + +void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material) +{ + struct MaterialFunctor : public LLSelectedTEGetFunctor + { + LLMaterialPtr get(LLViewerObject* object, S32 te_index) + { + return object->getTE(te_index)->getMaterialParams(); + } + } func; + identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr); +} + +void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical) +{ + struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + U32 s_axis = VX; + U32 t_axis = VY; + F32 repeats_s = 1.0f; + F32 repeats_t = 1.0f; + if (mat) + { + mat->getSpecularRepeat(repeats_s, repeats_t); + repeats_s /= object->getScale().mV[s_axis]; + repeats_t /= object->getScale().mV[t_axis]; + } + return llmax(repeats_s, repeats_t); + } + + } max_spec_repeats_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats); +} + +void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical) +{ + struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); + U32 s_axis = VX; + U32 t_axis = VY; + F32 repeats_s = 1.0f; + F32 repeats_t = 1.0f; + if (mat) + { + mat->getNormalRepeat(repeats_s, repeats_t); + repeats_s /= object->getScale().mV[s_axis]; + repeats_t /= object->getScale().mV[t_axis]; + } + return llmax(repeats_s, repeats_t); + } + + } max_norm_repeats_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats); +} + +void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha) +{ + struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor + { + LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {} + LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {} + virtual ~LLSelectedTEGetDiffuseAlphaMode() {} + + U8 get(LLViewerObject* object, S32 face) + { + U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + LLTextureEntry* tep = object->getTE(face); + if (tep) + { + LLMaterial* mat = tep->getMaterialParams().get(); + if (mat) + { + diffuse_mode = mat->getDiffuseAlphaMode(); + } + } + + return diffuse_mode; + } + bool _isAlpha; // whether or not the diffuse texture selected contains alpha information + } get_diff_mode(diffuse_texture_has_alpha); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); +} + +void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical) +{ + struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + return object->getScale().mV[s_axis]; + } + + } scale_s_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s ); +} + +void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical) +{ + struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + return object->getScale().mV[t_axis]; + } + + } scale_t_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t ); +} + +void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical) +{ + struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis]; + F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis]; + return llmax(repeats_s, repeats_t); + } + + } max_diff_repeats_func; + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); +} + static LLSD textures; void LLPanelFace::onClickCopy(void* userdata) @@ -1285,3 +2511,101 @@ void LLPanelFace::onClickPaste(void* userdata) msg->sendReliable(gAgent.getRegion()->getHost()); } + +// Materials alignment +void LLPanelFace::onClickMapsSync() +{ + getState(); + if (gSavedSettings.getBOOL("FSSynchronizeTextureMaps")) + { + alignMaterialsProperties(); + } +} + +void LLPanelFace::alignMaterialsProperties() +{ + F32 tex_scale_u = getChildView("TexScaleU")->getValue().asReal(); + F32 tex_scale_v = getChildView("TexScaleV")->getValue().asReal(); + F32 tex_offset_u = getChildView("TexOffsetU")->getValue().asReal(); + F32 tex_offset_v = getChildView("TexOffsetU")->getValue().asReal(); + F32 tex_rot = getChildView("TexRot")->getValue().asReal(); + + childSetValue("shinyScaleU", tex_scale_u); + childSetValue("shinyScaleV", tex_scale_v); + childSetValue("shinyOffsetU", tex_offset_u); + childSetValue("shinyOffsetV", tex_offset_v); + childSetValue("shinyRot", tex_rot); + + LLSelectedTEMaterial::setSpecularRepeatX(this, tex_scale_u); + LLSelectedTEMaterial::setSpecularRepeatY(this, tex_scale_v); + LLSelectedTEMaterial::setSpecularOffsetX(this, tex_offset_u); + LLSelectedTEMaterial::setSpecularOffsetY(this, tex_offset_v); + LLSelectedTEMaterial::setSpecularRotation(this, tex_rot * DEG_TO_RAD); + + childSetValue("bumpyScaleU", tex_scale_u); + childSetValue("bumpyScaleV", tex_scale_v); + childSetValue("bumpyOffsetU", tex_offset_u); + childSetValue("bumpyOffsetV", tex_offset_v); + childSetValue("bumpyRot", tex_rot); + + LLSelectedTEMaterial::setNormalRepeatX(this, tex_scale_u); + LLSelectedTEMaterial::setNormalRepeatY(this, tex_scale_v); + LLSelectedTEMaterial::setNormalOffsetX(this, tex_offset_u); + LLSelectedTEMaterial::setNormalOffsetY(this, tex_offset_v); + LLSelectedTEMaterial::setNormalRotation(this, tex_rot * DEG_TO_RAD); +} + +// FIRE-11407 - Flip buttons +void LLPanelFace::onCommitFlip(bool flip_x) +{ + std::string control_name = ""; + S32 mattype(getChild("combobox mattype")->getCurrentIndex()); + switch (mattype) + { + case MATTYPE_DIFFUSE: + control_name = "TexScale"; + break; + case MATTYPE_NORMAL: + control_name = "bumpyScale"; + break; + case MATTYPE_SPECULAR: + control_name = "shinyScale"; + break; + default: + //llassert(mattype); + return; + } + + if (LLUICtrl* spinner = getChild(control_name + (flip_x ? "U" : "V"))) + { + F32 value = -(spinner->getValue().asReal()); + spinner->setValue(value); + + switch (mattype) + { + case MATTYPE_DIFFUSE: + sendTextureInfo(); + if (gSavedSettings.getBOOL("FSSyncronizeTextureMaps")) + { + alignMaterialsProperties(); + } + break; + case MATTYPE_NORMAL: + if (flip_x) + LLSelectedTEMaterial::setNormalRepeatX(this, value); + else + LLSelectedTEMaterial::setNormalRepeatY(this, value); + break; + case MATTYPE_SPECULAR: + if (flip_x) + LLSelectedTEMaterial::setSpecularRepeatX(this, value); + else + LLSelectedTEMaterial::setSpecularRepeatY(this, value); + break; + default: + //llassert(mattype); + return; + } + } +} +// diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 52ccbaf10..5ac63c20b 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -35,6 +35,10 @@ #include "v4color.h" #include "llpanel.h" +#include "llmaterial.h" +#include "llmaterialmgr.h" +#include "lltextureentry.h" +#include "llselectmgr.h" class LLButton; class LLCheckBoxCtrl; @@ -47,6 +51,49 @@ class LLTextBox; class LLTextureCtrl; class LLUICtrl; class LLViewerObject; +class LLFloater; +class LLMaterialID; + +// Represents an edit for use in replicating the op across one or more materials in the selection set. +// +// The apply function optionally performs the edit which it implements +// as a functor taking Data that calls member func MaterialFunc taking SetValueType +// on an instance of the LLMaterial class. +// +// boost who? +// +template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > +class LLMaterialEditFunctor +{ +public: + LLMaterialEditFunctor(const DataType& data) : _data(data) {} + virtual ~LLMaterialEditFunctor() {} + virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); } + DataType _data; +}; + +template< + typename DataType, + DataType (LLMaterial::*MaterialGetFunc)() > +class LLMaterialGetFunctor +{ +public: + LLMaterialGetFunctor() {} + virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); } +}; + +template< + typename DataType, + DataType (LLTextureEntry::*TEGetFunc)() > +class LLTEGetFunctor +{ +public: + LLTEGetFunctor() {} + virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); } +}; class LLPanelFace : public LLPanel { @@ -59,6 +106,19 @@ public: void setMediaURL(const std::string& url); void setMediaType(const std::string& mime_type); + LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) + { + LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); + llassert_always(new_material); + + // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture + // + new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); + return new_material; + } + + LLRender::eTexIndex getTextureChannelToEdit(); + protected: void getState(); @@ -66,11 +126,11 @@ protected: void sendTextureInfo(); // applies and sends texture scale, offset, etc. void sendColor(); // applies and sends color void sendAlpha(); // applies and sends transparency - void sendBump(); // applies and sends bump map + void sendBump(U32 bumpiness); // applies and sends bump map void sendTexGen(); // applies and sends bump map - void sendShiny(); // applies and sends shininess + void sendShiny(U32 shininess); // applies and sends shininess void sendFullbright(); // applies and sends full bright - void sendGlow(); + void sendGlow(); void sendMedia(); // this function is to return TRUE if the drag should succeed. @@ -79,23 +139,370 @@ protected: void onCommitTexture(const LLSD& data); void onCancelTexture(const LLSD& data); void onSelectTexture(const LLSD& data); + void onCommitSpecularTexture(const LLSD& data); + void onCancelSpecularTexture(const LLSD& data); + void onSelectSpecularTexture(const LLSD& data); + void onCommitNormalTexture(const LLSD& data); + void onCancelNormalTexture(const LLSD& data); + void onSelectNormalTexture(const LLSD& data); void onCommitColor(const LLSD& data); + void onCommitShinyColor(const LLSD& data); void onCommitAlpha(const LLSD& data); void onCancelColor(const LLSD& data); void onSelectColor(const LLSD& data); + + void onCloseTexturePicker(const LLSD& data); + + // Make UI reflect state of currently selected material (refresh) + // and UI mode (e.g. editing normal map v diffuse map) + // + void updateUI(); + + // Convenience func to determine if all faces in selection have + // identical planar texgen settings during edits + // + bool isIdenticalPlanarTexgen(); + + // Callback funcs for individual controls + // static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata); + + static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); + void onCommitMaterialType(); static void onCommitBump( LLUICtrl* ctrl, void* userdata); static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); static void onCommitShiny( LLUICtrl* ctrl, void* userdata); + static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata); static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); static void onCommitGlow( LLUICtrl* ctrl, void *userdata); static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); - static void onClickApply(void*); + static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); static void onClickAutoFix(void*); - static void onClickCopy(void*); - static void onClickPaste(void*); static F32 valueGlow(LLViewerObject* object, S32 face); + static void onClickCopy(void*); + static void onClickPaste(void*); + // Build tool enhancements + void onClickMapsSync(); + void alignMaterialsProperties(); + void onCommitFlip(bool flip_x); + // + +private: + + bool isAlpha() { return mIsAlpha; } + + // Convenience funcs to keep the visual flack to a minimum + // + LLUUID getCurrentNormalMap(); + LLUUID getCurrentSpecularMap(); + U32 getCurrentShininess(); + U32 getCurrentBumpiness(); + U8 getCurrentDiffuseAlphaMode(); + U8 getCurrentAlphaMaskCutoff(); + U8 getCurrentEnvIntensity(); + U8 getCurrentGlossiness(); + F32 getCurrentBumpyRot(); + F32 getCurrentBumpyScaleU(); + F32 getCurrentBumpyScaleV(); + F32 getCurrentBumpyOffsetU(); + F32 getCurrentBumpyOffsetV(); + F32 getCurrentShinyRot(); + F32 getCurrentShinyScaleU(); + F32 getCurrentShinyScaleV(); + F32 getCurrentShinyOffsetU(); + F32 getCurrentShinyOffsetV(); + + // Update visibility of controls to match current UI mode + // (e.g. materials vs media editing) + // + // Do NOT call updateUI from within this function. + // + void updateVisibility(); + + // Make material(s) reflect current state of UI (apply edit) + // + void updateMaterial(); + + // Hey look everyone, a type-safe alternative to copy and paste! :) + // + + // Update material parameters by applying 'edit_func' to selected TEs + // + template< + typename DataType, + typename SetValueType, + void (LLMaterial::*MaterialEditFunc)(SetValueType data) > + static void edit(LLPanelFace* p, DataType data) + { + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data); + struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor + { + LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp) : _panel(panel), _edit(editp) {} + virtual ~LLSelectedTEEditMaterial() {}; + virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) + { + if (_edit) + { + LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material); + llassert_always(new_material); + + // Determine correct alpha mode for current diffuse texture + // (i.e. does it have an alpha channel that makes alpha mode useful) + // + // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329) + // need to get per-face answer to this question for sane alpha mode retention on updates. + // + bool is_alpha_face = object->isImageAlphaBlended(face); + + // need to keep this original answer for valid comparisons in logic below + // + U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + U8 default_alpha_mode = original_default_alpha_mode; + + if (!current_material.isNull()) + { + default_alpha_mode = current_material->getDiffuseAlphaMode(); + } + + // Ensure we don't inherit the default of blend by accident... + // this will be stomped by a legit request to change the alpha mode by the apply() below + // + new_material->setDiffuseAlphaMode(default_alpha_mode); + + // Do "It"! + // + _edit->apply(new_material); + + U32 new_alpha_mode = new_material->getDiffuseAlphaMode(); + LLUUID new_normal_map_id = new_material->getNormalID(); + LLUUID new_spec_map_id = new_material->getSpecularID(); + + if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face) + { + new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); + } + + bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode); + bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull(); + + if (!is_need_material) + { + LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; + LLMaterialMgr::getInstance()->remove(object->getID(),face); + new_material = NULL; + } + else + { + LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL; + LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material); + } + + object->setTEMaterialParams(face, new_material); + return new_material; + } + return NULL; + } + LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit; + LLPanelFace* _panel; + } editor(p, &edit); + LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor); + } + + template< + typename DataType, + typename ReturnType, + ReturnType (LLMaterial::* const MaterialGetFunc)() const > + static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value) + { + DataType data_value; + struct GetTEMaterialVal : public LLSelectedTEGetFunctor + { + GetTEMaterialVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEMaterialVal() {} + + DataType get(LLViewerObject* object, S32 face) + { + DataType ret = _default; + LLMaterialPtr material_ptr; + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + if (tep) + { + material_ptr = tep->getMaterialParams(); + if (!material_ptr.isNull()) + { + ret = (material_ptr->*(MaterialGetFunc))(); + } + } + return ret; + } + DataType _default; + } GetFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value); + data_to_return = data_value; + } + + template< + typename DataType, + typename ReturnType, // some kids just have to different... + ReturnType (LLTextureEntry::* const TEGetFunc)() const > + static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value) + { + DataType data_value; + struct GetTEVal : public LLSelectedTEGetFunctor + { + GetTEVal(DataType default_value) : _default(default_value) {} + virtual ~GetTEVal() {} + + DataType get(LLViewerObject* object, S32 face) { + LLTextureEntry* tep = object ? object->getTE(face) : NULL; + return tep ? ((tep->*(TEGetFunc))()) : _default; + } + DataType _default; + } GetTEValFunc(default_value); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value ); + data_to_return = data_value; + } + + // Update vis and enabling of specific subsets of controls based on material params + // (e.g. hide the spec controls if no spec texture is applied) + // + void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false); + void updateAlphaControls(); + + /* + * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object. + * If agent selects texture which is not allowed to be applied for the currently selected object, + * all controls of the floater texture picker which allow to apply the texture will be disabled. + */ + void onTextureSelectionChanged(LLInventoryItem* itemp); + + bool mIsAlpha; + + + #if defined(DEF_GET_MAT_STATE) + #undef DEF_GET_MAT_STATE + #endif + + #if defined(DEF_GET_TE_STATE) + #undef DEF_GET_TE_STATE + #endif + + #if defined(DEF_EDIT_MAT_STATE) + DEF_EDIT_MAT_STATE + #endif + + // Accessors for selected TE material state + // + #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue) \ + static void MaterialMemberFunc(DataType& data, bool& identical) \ + { \ + getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical,DefaultValue); \ + } + + // Mutators for selected TE material + // + #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc) \ + static void MaterialMemberFunc(LLPanelFace* p,DataType data) \ + { \ + edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p,data); \ + } + + // Accessors for selected TE state proper (legacy settings etc) + // + #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue) \ + static void TexEntryMemberFunc(DataType& data, bool& identical) \ + { \ + getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical,DefaultValue); \ + } + + class LLSelectedTEMaterial + { + public: + static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material); + static void getMaxSpecularRepeats(F32& repeats, bool& identical); + static void getMaxNormalRepeats(F32& repeats, bool& identical); + static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null) + DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f) + DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f) + DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f) + + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f) + DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f) + DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f) + DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f) + + DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode); + DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff); + + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation); + + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY); + DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation); + + DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity); + DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent); + + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); + DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); + DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); + }; + + class LLSelectedTE + { + public: + + static void getFace(LLFace*& face_to_return, bool& identical_face); + static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face); + static void getTexId(LLUUID& id, bool& identical); + static void getObjectScaleS(F32& scale_s, bool& identical); + static void getObjectScaleT(F32& scale_t, bool& identical); + static void getMaxDiffuseRepeats(F32& repeats, bool& identical); + + DEF_GET_TE_STATE(U8,U8,getBumpmap,0) + DEF_GET_TE_STATE(U8,U8,getShiny,0) + DEF_GET_TE_STATE(U8,U8,getFullbright,0) + DEF_GET_TE_STATE(F32,F32,getRotation,0.0f) + DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f) + DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f) + DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f) + DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f) + DEF_GET_TE_STATE(F32,F32,getGlow,0.0f) + DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT) + DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white) + }; }; #endif diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 42facc56c..f9ad87f55 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -1118,16 +1118,17 @@ void LLPanelPermissions::onClickDeedToGroup(void* data) LLNotificationsUtil::add( "DeedObjectToGroup", LLSD(), LLSD(), callback_deed_to_group); } -void LLPanelPermissions::onClickCopyObjKey() +template +std::string gather_keys(iterator iter, iterator end) { //NAMESHORT - Was requested on the forums, was going to integrate a textbox with the ID, but due to lack of room on the floater, //We now have a copy button :> //Madgeek - Hacked together method to copy more than one key, separated by comma. //At some point the separator was changed to read from the xml settings - I'll probably try to make this openly changable from settings. -HgB + //Lirusaito - Tweaked to copy selected prim(s) when EditLinkedParts, main functionality moved into gather_keys std::string output; std::string separator = gSavedSettings.getString("AscentDataSeparator"); - for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++) + for (; iter != end; ++iter) { LLSelectNode* selectNode = *iter; LLViewerObject* object = selectNode->getObject(); @@ -1137,6 +1138,14 @@ void LLPanelPermissions::onClickCopyObjKey() output.append(object->getID().asString()); } } + return output; +} + +void LLPanelPermissions::onClickCopyObjKey() +{ + bool parts(gSavedSettings.getBOOL("EditLinkedParts")); + LLObjectSelectionHandle selection(LLSelectMgr::getInstance()->getSelection()); + std::string output = parts ? gather_keys(selection->begin(), selection->end()) : gather_keys(selection->root_begin(), selection->root_end()); if (!output.empty()) gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(output)); } diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 442673c0c..6ea6e1ba8 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -66,6 +66,7 @@ public: // llview virtual void draw(); + virtual bool hasAccelerators() const { return true; } virtual BOOL handleKeyHere(KEY key, MASK mask); virtual void setEnabled( BOOL enabled ); virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index ace3f9949..906708333 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -128,6 +128,8 @@ public: static BOOL enableSelectAllMenu(void* userdata); static BOOL enableDeselectMenu(void* userdata); + virtual bool hasAccelerators() const { return true; } + private: static bool onHelpWebDialog(const LLSD& notification, const LLSD& response); static void onBtnHelp(void* userdata); diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp index 163ba6056..7992ee558 100644 --- a/indra/newview/llpreviewsound.cpp +++ b/indra/newview/llpreviewsound.cpp @@ -60,10 +60,36 @@ const F32 SOUND_GAIN = 1.0f; LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid) : LLPreview( name, rect, title, item_uuid, object_uuid) +, mIsCopyable(false) { LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_sound.xml"); + setTitle(title); + + if (!getHost()) + { + LLRect curRect = getRect(); + translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop); + } +} + +// virtual +BOOL LLPreviewSound::postBuild() +{ + const LLInventoryItem* item = getItem(); + if (item) + { + getChild("desc")->setValue(item->getDescription()); + mIsCopyable = (item->getPermissions().getCreator() == gAgentID); + if (gAudiop) + // + // that thing above doesn't actually start a sound transfer, so I will do it + if (LLAudioSource* asp = gAgentAvatarp->getAudioSource(gAgentID)) + asp->preload(item->getAssetUUID()); // preload the sound + // + } + childSetAction("Sound play btn",&LLPreviewSound::playSound,this); childSetAction("Sound audition btn",&LLPreviewSound::auditionSound,this); // @@ -77,40 +103,10 @@ LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, cons button = getChild("Sound audition btn"); button->setSoundFlags(LLView::SILENT); - const LLInventoryItem* item = getItem(); - - mIsCopyable = false; - if(item) - { - const LLPermissions& perm = item->getPermissions(); - mIsCopyable = (perm.getCreator() == gAgent.getID()); - } - childSetCommitCallback("desc", LLPreview::onText, this); - childSetText("desc", item->getDescription()); getChild("desc")->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe); - - // preload the sound - if(item && gAudiop) - { - // - // that thing above doesn't actually start a sound transfer, so I will do it - LLAudioSource *asp = gAgentAvatarp->getAudioSource(gAgent.getID()); - if(asp) - { - asp->preload(item->getAssetUUID()); - } - // - } - - setTitle(title); - - if (!getHost()) - { - LLRect curRect = getRect(); - translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop); - } + return LLPreview::postBuild(); } // static diff --git a/indra/newview/llpreviewsound.h b/indra/newview/llpreviewsound.h index 6d8928c97..51a89d9df 100644 --- a/indra/newview/llpreviewsound.h +++ b/indra/newview/llpreviewsound.h @@ -65,6 +65,7 @@ public: // protected: + /*virtual*/ BOOL postBuild(); virtual const char *getTitleName() const { return "Sound"; } // virtual BOOL canSaveAs() const; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 7bd68ad4a..f16409e32 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -29,6 +29,7 @@ // file include #define LLSELECTMGR_CPP #include "llselectmgr.h" +#include "llmaterialmgr.h" // library includes #include "llcachename.h" @@ -64,6 +65,7 @@ #include "llmenugl.h" #include "llmeshrepository.h" #include "llmutelist.h" +#include "llparcel.h" #include "llnotificationsutil.h" #include "llstatusbar.h" #include "llsurface.h" @@ -80,20 +82,18 @@ #include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" +#include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "llvoavatarself.h" #include "llvovolume.h" #include "pipeline.h" #include "llviewershadermgr.h" - -#include "llparcel.h" -#include "llviewerparcelmgr.h" - +#include "llpanelface.h" #include "llglheaders.h" #include "hippogridmanager.h" -// [RLVa:KB] +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvhandler.h" // [/RLVa:KB] @@ -191,6 +191,7 @@ LLSelectMgr::LLSelectMgr() mDebugSelectMgr(LLCachedControl( "DebugSelectMgr", false)) { mTEMode = FALSE; + mTextureChannel = LLRender::DIFFUSE_MAP; mLastCameraPos.clearVec(); sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness"); @@ -214,7 +215,6 @@ LLSelectMgr::LLSelectMgr() mGridMode = GRID_MODE_WORLD; gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD); - mGridValid = FALSE; mSelectedObjects = new LLObjectSelection(); mHoverObjects = new LLObjectSelection(); @@ -240,6 +240,8 @@ void LLSelectMgr::clearSelections() mHighlightedObjects->deleteAllNodes(); mRectSelectedObjects.clear(); mGridObjects.deleteAllNodes(); + + LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP); } void LLSelectMgr::update() @@ -869,6 +871,10 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab // check to see if object is already in list LLSelectNode *nodep = mSelectedObjects->findNode(objectp); + // Reset (in anticipation of being set to an appropriate value by panel refresh, if they're up) + // + setTextureChannel(LLRender::DIFFUSE_MAP); + // if not in list, add it if (!nodep) { @@ -1202,7 +1208,6 @@ void LLSelectMgr::setGridMode(EGridMode mode) mGridMode = mode; gSavedSettings.setS32("GridMode", mode); updateSelectionCenter(); - mGridValid = FALSE; } void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale) @@ -1303,7 +1308,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & origin = mGridOrigin; rotation = mGridRotation; scale = mGridScale; - mGridValid = TRUE; } //----------------------------------------------------------------------------- @@ -2008,6 +2012,76 @@ void LLSelectMgr::selectionSetGlow(F32 glow) mSelectedObjects->applyToObjects( &func2 ); } +void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func) +{ + struct f1 : public LLSelectedTEFunctor + { + LLMaterialPtr mMaterial; + f1(LLSelectedTEMaterialFunctor* material_func) : _material_func(material_func) {} + + bool apply(LLViewerObject* object, S32 face) + { + if (object && object->permModify() && _material_func) + { + LLTextureEntry* tep = object->getTE(face); + if (tep) + { + LLMaterialPtr current_material = tep->getMaterialParams(); + _material_func->apply(object, face, tep, current_material); + } + } + return true; + } + + LLSelectedTEMaterialFunctor* _material_func; + } func1(material_func); + mSelectedObjects->applyToTEs( &func1 ); + + struct f2 : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + return true; + } + } func2; + mSelectedObjects->applyToObjects( &func2 ); +} + +void LLSelectMgr::selectionRemoveMaterial() +{ + struct f1 : public LLSelectedTEFunctor + { + bool apply(LLViewerObject* object, S32 face) + { + if (object->permModify()) + { + LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL; + LLMaterialMgr::getInstance()->remove(object->getID(),face); + object->setTEMaterialParams(face, NULL); + } + return true; + } + } func1; + mSelectedObjects->applyToTEs( &func1 ); + + struct f2 : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + return true; + } + } func2; + mSelectedObjects->applyToObjects( &func2 ); +} + //----------------------------------------------------------------------------- // findObjectPermissions() @@ -2048,6 +2122,7 @@ BOOL LLSelectMgr::selectionGetGlow(F32 *glow) return identical; } + void LLSelectMgr::selectionSetPhysicsType(U8 type) { struct f : public LLSelectedObjectFunctor @@ -2143,6 +2218,7 @@ void LLSelectMgr::selectionSetRestitution(F32 restitution) getSelection()->applyToObjects(&sendfunc); } + //----------------------------------------------------------------------------- // selectionSetMaterial() //----------------------------------------------------------------------------- @@ -2427,19 +2503,66 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) continue; } - LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num]; LLVector3 object_scale = object->getScale(); + LLVector3 diffuse_scale_ratio = selectNode->mTextureScaleRatios[te_num]; + + // We like these to track together. NORSPEC-96 + // + LLVector3 normal_scale_ratio = diffuse_scale_ratio; + LLVector3 specular_scale_ratio = diffuse_scale_ratio; // Apply new scale to face if (planar) { - object->setTEScale(te_num, 1.f/object_scale.mV[s_axis]*scale_ratio.mV[s_axis], - 1.f/object_scale.mV[t_axis]*scale_ratio.mV[t_axis]); + F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; + F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + + F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; + F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + + F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis]; + F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis]; + + object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t); + + LLTextureEntry* tep = object->getTE(te_num); + + if (tep && !tep->getMaterialParams().isNull()) + { + LLMaterialPtr orig = tep->getMaterialParams(); + LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); + p->setNormalRepeat(normal_scale_s, normal_scale_t); + p->setSpecularRepeat(specular_scale_s, specular_scale_t); + + LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); + } } else { - object->setTEScale(te_num, scale_ratio.mV[s_axis]*object_scale.mV[s_axis], - scale_ratio.mV[t_axis]*object_scale.mV[t_axis]); + + F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; + F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + + F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; + F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + + F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis]; + F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis]; + + object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t); + + LLTextureEntry* tep = object->getTE(te_num); + + if (tep && !tep->getMaterialParams().isNull()) + { + LLMaterialPtr orig = tep->getMaterialParams(); + LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); + + p->setNormalRepeat(normal_scale_s, normal_scale_t); + p->setSpecularRepeat(specular_scale_s, specular_scale_t); + + LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p); + } } send = send_to_sim; } @@ -2892,7 +3015,6 @@ BOOL LLSelectMgr::selectGetViewableCharacters() return TRUE; } - //----------------------------------------------------------------------------- // selectGetRootsTransfer() - return TRUE if current agent can transfer all // selected root objects. @@ -3410,13 +3532,13 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, case 0: { // TODO: Make sure you have delete permissions on all of them. - LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); // attempt to derez into the trash. - LLDeRezInfo* info = new LLDeRezInfo(DRD_TRASH, trash_id); + LLDeRezInfo info(DRD_TRASH, trash_id); LLSelectMgr::getInstance()->sendListToRegions("DeRezObject", packDeRezHeader, packObjectLocalID, - (void*)info, + (void*) &info, SEND_ONLY_ROOTS); // VEFFECT: Delete Object - one effect for all deletes if(!gSavedSettings.getBOOL("DisablePointAtAndBeam")) @@ -4164,13 +4286,15 @@ void LLSelectMgr::deselectAllIfTooFar() void LLSelectMgr::selectionSetObjectName(const std::string& name) { + std::string name_copy(name); + // we only work correctly if 1 object is selected. if(mSelectedObjects->getRootObjectCount() == 1) { sendListToRegions("ObjectName", packAgentAndSessionID, packObjectName, - (void*)(new std::string(name)), + (void*)(&name_copy), SEND_ONLY_ROOTS); } else if(mSelectedObjects->getObjectCount() == 1) @@ -4178,20 +4302,22 @@ void LLSelectMgr::selectionSetObjectName(const std::string& name) sendListToRegions("ObjectName", packAgentAndSessionID, packObjectName, - (void*)(new std::string(name)), + (void*)(&name_copy), SEND_INDIVIDUALS); } } void LLSelectMgr::selectionSetObjectDescription(const std::string& desc) { + std::string desc_copy(desc); + // we only work correctly if 1 object is selected. if(mSelectedObjects->getRootObjectCount() == 1) { sendListToRegions("ObjectDescription", packAgentAndSessionID, packObjectDescription, - (void*)(new std::string(desc)), + (void*)(&desc_copy), SEND_ONLY_ROOTS); } else if(mSelectedObjects->getObjectCount() == 1) @@ -4199,7 +4325,7 @@ void LLSelectMgr::selectionSetObjectDescription(const std::string& desc) sendListToRegions("ObjectDescription", packAgentAndSessionID, packObjectDescription, - (void*)(new std::string(desc)), + (void*)(&desc_copy), SEND_INDIVIDUALS); } } @@ -4472,7 +4598,8 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type) struct f : public LLSelectedNodeFunctor { EActionType mActionType; - f(EActionType a) : mActionType(a) {} + LLSelectMgr* mManager; + f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {} virtual bool apply(LLSelectNode* selectNode) { LLViewerObject* object = selectNode->getObject(); @@ -4519,10 +4646,10 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type) } selectNode->mSavedScale = object->getScale(); - selectNode->saveTextureScaleRatios(); + selectNode->saveTextureScaleRatios(mManager->mTextureChannel); return true; } - } func(action_type); + } func(action_type, this); getSelection()->applyToNodes(&func); mSavedSelectionBBox = getBBoxOfSelection(); @@ -4726,7 +4853,6 @@ void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data) gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID()); gMessageSystem->addStringFast(_PREHASH_Name, *name); } - delete name; } // static @@ -5850,36 +5976,42 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures) } } -void LLSelectNode::saveTextureScaleRatios() +void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) { mTextureScaleRatios.clear(); + if (mObject.notNull()) { + LLVector3 scale = mObject->getScale(); + for (U8 i = 0; i < mObject->getNumTEs(); i++) { - F32 s,t; - const LLTextureEntry* tep = mObject->getTE(i); - tep->getScale(&s,&t); - U32 s_axis = 0; - U32 t_axis = 0; - - LLPrimitive::getTESTAxes(i, &s_axis, &t_axis); + F32 diffuse_s = 1.0f; + F32 diffuse_t = 1.0f; LLVector3 v; - LLVector3 scale = mObject->getScale(); + const LLTextureEntry* tep = mObject->getTE(i); + if (!tep) + continue; + + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(i, &s_axis, &t_axis); + + tep->getScale(&diffuse_s,&diffuse_t); if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR) { - v.mV[s_axis] = s*scale.mV[s_axis]; - v.mV[t_axis] = t*scale.mV[t_axis]; + v.mV[s_axis] = diffuse_s*scale.mV[s_axis]; + v.mV[t_axis] = diffuse_t*scale.mV[t_axis]; + mTextureScaleRatios.push_back(v); } else { - v.mV[s_axis] = s/scale.mV[s_axis]; - v.mV[t_axis] = t/scale.mV[t_axis]; + v.mV[s_axis] = diffuse_s/scale.mV[s_axis]; + v.mV[t_axis] = diffuse_t/scale.mV[t_axis]; + mTextureScaleRatios.push_back(v); } - - mTextureScaleRatios.push_back(v); } } } @@ -6383,7 +6515,23 @@ void LLSelectMgr::updateSelectionCenter() if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) { - mPauseRequest = gAgentAvatarp->requestPause(); + // Singu Note: Chalice Yao's pause agent on attachment selection + if (object->permYouOwner()) + { + mPauseRequest = gAgentAvatarp->requestPause(); + } + else if (LLViewerObject* objectp = mSelectedObjects->getPrimaryObject()) + { + while (objectp && !objectp->isAvatar()) + { + objectp = (LLViewerObject*)objectp->getParent(); + } + + if (objectp) + { + mPauseRequest = objectp->asAvatar()->requestPause(); + } + } } else { @@ -6430,6 +6578,7 @@ void LLSelectMgr::updateSelectionCenter() LLVector3 bbox_center_agent = bbox.getCenterAgent(); mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent); mSelectionBBox = bbox; + } if ( !(gAgentID == LLUUID::null)) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 22175932f..ce16d0569 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -49,6 +49,7 @@ #include "llpermissions.h" #include "llcontrol.h" #include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template +#include "llmaterial.h" #include #include @@ -89,6 +90,12 @@ struct LLSelectedTEFunctor virtual bool apply(LLViewerObject* object, S32 face) = 0; }; +struct LLSelectedTEMaterialFunctor +{ + virtual ~LLSelectedTEMaterialFunctor() {}; + virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0; +}; + template struct LLSelectedTEGetFunctor { virtual ~LLSelectedTEGetFunctor() {}; @@ -149,7 +156,7 @@ public: // *NOTE: invalidate stored textures and colors when # faces change void saveColors(); void saveTextures(const uuid_vec_t& textures); - void saveTextureScaleRatios(); + void saveTextureScaleRatios(LLRender::eTexIndex index_to_query); BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const; @@ -272,6 +279,8 @@ public: LLViewerObject* getFirstCopyableObject(BOOL get_parent = FALSE); LLViewerObject* getFirstDeleteableObject(); LLViewerObject* getFirstMoveableObject(BOOL get_parent = FALSE); + + /// Return the object that lead to this selection, possible a child LLViewerObject* getPrimaryObject() { return mPrimaryObject; } // iterate through texture entries @@ -344,6 +353,7 @@ public: static BOOL sRectSelectInclusive; // do we need to surround an object to pick it? static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded? static BOOL sRenderLightRadius; // do we show the radius of selected lights? + static F32 sHighlightThickness; static F32 sHighlightUScale; static F32 sHighlightVScale; @@ -465,11 +475,11 @@ public: //////////////////////////////////////////////////////////////// // Selection accessors //////////////////////////////////////////////////////////////// + LLObjectSelectionHandle getHoverObjects() { return mHoverObjects; } LLObjectSelectionHandle getSelection() { return mSelectedObjects; } // right now this just renders the selection with root/child colors instead of a single color LLObjectSelectionHandle getEditSelection() { convertTransient(); return mSelectedObjects; } LLObjectSelectionHandle getHighlightedObjects() { return mHighlightedObjects; } - LLObjectSelectionHandle getHoverObjects() { return mHoverObjects; } //////////////////////////////////////////////////////////////// // Grid manipulation @@ -502,6 +512,11 @@ public: void saveSelectedObjectColors(); void saveSelectedObjectTextures(); + // Sets which texture channel to query for scale and rot of display + // and depends on UI state of LLPanelFace when editing + void setTextureChannel(LLRender::eTexIndex texIndex) { mTextureChannel = texIndex; } + LLRender::eTexIndex getTextureChannel() { return mTextureChannel; } + void selectionUpdatePhysics(BOOL use_physics); void selectionUpdateTemporary(BOOL is_temporary); void selectionUpdatePhantom(BOOL is_ghost); @@ -532,6 +547,8 @@ public: void selectionSetClickAction(U8 action); void selectionSetIncludeInSearch(bool include_in_search); void selectionSetGlow(const F32 glow); + void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func); + void selectionRemoveMaterial(); void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE); void selectionSetObjectName(const std::string& name); @@ -758,10 +775,9 @@ private: LLVector3 mGridOrigin; LLVector3 mGridScale; EGridMode mGridMode; - BOOL mGridValid; - BOOL mTEMode; // render te + LLRender::eTexIndex mTextureChannel; // diff, norm, or spec, depending on UI editing mode LLVector3d mSelectionCenterGlobal; LLBBox mSelectionBBox; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 75978675c..0cf590cd8 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -311,7 +311,7 @@ void reset_login(); void apply_udp_blacklist(const std::string& csv); // Aurora Sim //bool process_login_success_response(std::string& password); -bool process_login_success_response(std::string& password, U32& first_sim_size_x); +bool process_login_success_response(std::string& password, U32& first_sim_size_x, U32& first_sim_size_y); // Aurora Sim void transition_back_to_login_panel(const std::string& emsg); @@ -484,6 +484,7 @@ bool idle_startup() // Aurora Sim static U32 first_sim_size_x = 256; + static U32 first_sim_size_y = 256; // Aurora Sim static LLVector3 initial_sun_direction(1.f, 0.f, 0.f); static LLVector3 agent_start_position_region(10.f, 10.f, 10.f); // default for when no space server @@ -1550,7 +1551,7 @@ bool idle_startup() if (successful_login) { // unpack login data needed by the application - if (process_login_success_response(password, first_sim_size_x)) + if (process_login_success_response(password, first_sim_size_x, first_sim_size_y)) { std::string name = firstname; if (!gHippoGridManager->getCurrentGrid()->isSecondLife() || @@ -1670,7 +1671,7 @@ bool idle_startup() display_startup(); // Aurora Sim - LLWorld::getInstance()->setRegionWidth(first_sim_size_x); + LLWorld::getInstance()->setRegionSize(first_sim_size_x, first_sim_size_y); // Aurora Sim LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim); display_startup(); @@ -3856,7 +3857,7 @@ void apply_udp_blacklist(const std::string& csv) } -bool process_login_success_response(std::string& password, U32& first_sim_size_x) +bool process_login_success_response(std::string& password, U32& first_sim_size_x, U32& first_sim_size_y) { LLSD response = LLUserAuth::getInstance()->getResponse(); @@ -4000,6 +4001,9 @@ bool process_login_success_response(std::string& password, U32& first_sim_size_x // Aurora Sim text = response["region_size_x"].asString(); if (!text.empty()) LLViewerParcelMgr::getInstance()->init(first_sim_size_x = atoi(text.c_str())); + // Patrick Sapinski commented here on 2/10/2011 that y is currently unused and major refactor is required - Liru (11/6/2013) + text = response["region_size_y"].asString(); + if (!text.empty()) first_sim_size_y = atoi(text.c_str()); // Aurora Sim const std::string look_at_str = response["look_at"]; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index ca53a8f6c..d17c6316d 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -141,6 +141,8 @@ public: // New functions void setImageID( const LLUUID& image_asset_id); + const LLUUID& getWhiteImageAssetID() const { return mWhiteImageAssetID; } + void setWhiteImageAssetID(const LLUUID& id) { mWhiteImageAssetID = id; } void updateImageStats(); const LLUUID& getAssetID() { return mImageAssetID; } const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only); @@ -158,6 +160,9 @@ public: void updateFilterPermMask(); void commitIfImmediateSet(); + void setCanApply(bool can_preview, bool can_apply); + void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;} + static void onBtnSetToDefault( void* userdata ); static void onBtnSelect( void* userdata ); static void onBtnCancel( void* userdata ); @@ -220,6 +225,11 @@ protected: LLSaveFolderState mSavedFolderState; BOOL mSelectedItemPinned; LLScrollListCtrl* mLocalScrollCtrl; // tag: vaa emerald local_asset_browser + +private: + bool mCanApply; + bool mCanPreview; + texture_selected_callback mTextureSelectedCallback; }; LLFloaterTexturePicker::LLFloaterTexturePicker( @@ -254,7 +264,9 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mDnDFilterPermMask(dnd_filter_perm_mask), mNonImmediateFilterPermMask(non_immediate_filter_perm_mask), mContextConeOpacity(0.f), - mSelectedItemPinned(FALSE) + mSelectedItemPinned(FALSE), + mCanApply(true), + mCanPreview(true) { mCanApplyImmediately = can_apply_immediately; LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml"); @@ -353,7 +365,9 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( { BOOL handled = FALSE; - if (cargo_type == DAD_TEXTURE) + bool is_mesh = cargo_type == DAD_MESH; + + if ((cargo_type == DAD_TEXTURE) || is_mesh) { LLInventoryItem *item = (LLInventoryItem *)cargo_data; @@ -373,6 +387,9 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( { if (drop) { + // FIRE-8298: Apply now checkbox has no effect + setCanApply(true, true); + // setImageID( item->getAssetUUID() ); commitIfImmediateSet(); } @@ -607,7 +624,7 @@ void LLFloaterTexturePicker::draw() // if we're inactive, gray out "apply immediate" checkbox getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected); - getChildView("Select")->setEnabled(mActive); + getChildView("Select")->setEnabled(mActive && mCanApply); getChildView("Pipette")->setEnabled(mActive); getChild("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); @@ -768,8 +785,10 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask() void LLFloaterTexturePicker::commitIfImmediateSet() { - bool apply_immediate = getChild("apply_immediate_check")->getValue().asBoolean(); - if (!mNoCopyTextureSelected && mOwner && apply_immediate) + // FIRE-8298: Apply now checkbox has no effect + //if (!mNoCopyTextureSelected && mOwner && mCanApply) + if (!mNoCopyTextureSelected && mOwner && mCanApply && mCanPreview) + // { mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE); } @@ -779,6 +798,7 @@ void LLFloaterTexturePicker::commitIfImmediateSet() void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); if (self->mOwner) { self->setImageID( self->mOwner->getDefaultImageAssetID() ); @@ -790,6 +810,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata) void LLFloaterTexturePicker::onBtnWhite(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); self->setImageID( self->mWhiteImageAssetID ); self->commitIfImmediateSet(); } @@ -798,6 +819,7 @@ void LLFloaterTexturePicker::onBtnWhite(void* userdata) void LLFloaterTexturePicker::onBtnNone(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); self->setImageID( LLUUID::null ); self->commitIfImmediateSet(); } @@ -806,6 +828,7 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata) void LLFloaterTexturePicker::onBtnInvisible(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); self->setImageID(self->mInvisibleImageAssetID); self->commitIfImmediateSet(); } @@ -815,6 +838,7 @@ void LLFloaterTexturePicker::onBtnInvisible(void* userdata) void LLFloaterTexturePicker::onBtnAlpha(void* userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; + self->setCanApply(true, true); self->setImageID(self->mAlphaImageAssetID); self->commitIfImmediateSet(); } @@ -959,6 +983,10 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque if (itemp->getPermissions().getMaskOwner() & PERM_ALL) childSetValue("texture_uuid", mImageAssetID); @@ -970,9 +998,12 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque FIRE-8298: Apply now checkbox has no effect + setCanApply(true, true); + // mImageAssetID = itemp->getAssetUUID(); mIsDirty = TRUE; - if (user_action) + if (user_action && mCanPreview) { // only commit intentional selections, not implicit ones commitIfImmediateSet(); @@ -1004,7 +1035,9 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; gSavedSettings.setBOOL("ApplyTextureImmediately", check_box->get()); - + // FIRE-8298: Apply now checkbox has no effect + picker->setCanApply(true, true); + // picker->updateFilterPermMask(); picker->commitIfImmediateSet(); } @@ -1014,6 +1047,16 @@ void LLFloaterTexturePicker::updateFilterPermMask() //mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss. } +void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply) +{ + getChildRef("Select").setEnabled(can_apply); + getChildRef("preview_disabled").setVisible(!can_preview); + getChildRef("apply_immediate_check").setVisible(can_preview); + + mCanApply = can_apply; + mCanPreview = can_preview ? gSavedSettings.getBOOL("ApplyTextureImmediately") : false; +} + void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) { std::string upper_case_search_string = search_string; @@ -1054,6 +1097,9 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) if (inventory_item_id.notNull()) { LLToolPipette::getInstance()->setResult(TRUE, ""); + // FIRE-8298: Apply now checkbox has no effect + setCanApply(true, true); + // setImageID(te.getID()); mNoCopyTextureSelected = FALSE; @@ -1094,6 +1140,7 @@ LLTextureCtrl::LLTextureCtrl( mDragCallback(NULL), mDropCallback(NULL), mOnCancelCallback(NULL), + mOnCloseCallback(NULL), mOnSelectCallback(NULL), mBorderColor( gColors.getColor("DefaultHighlightLight") ), mImageAssetID( image_id ), @@ -1221,6 +1268,19 @@ void LLTextureCtrl::setShowLoadingPlaceholder(BOOL showLoadingPlaceholder) mShowLoadingPlaceholder = showLoadingPlaceholder; } +// Singu Note: These two functions exist to work like their upstream counterparts +void LLTextureCtrl::setBlankImageAssetID(const LLUUID& id) +{ + if (LLFloaterTexturePicker* floater = dynamic_cast(mFloaterHandle.get())) + floater->setWhiteImageAssetID(id); +} +const LLUUID& LLTextureCtrl::getBlankImageAssetID() const +{ + if (LLFloaterTexturePicker* floater = dynamic_cast(mFloaterHandle.get())) + return floater->getWhiteImageAssetID(); + return LLUUID::null; +} + void LLTextureCtrl::setCaption(const std::string& caption) { mCaption->setText( caption ); @@ -1236,6 +1296,15 @@ void LLTextureCtrl::setCanApplyImmediately(BOOL b) } } +void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply) +{ + LLFloaterTexturePicker* floaterp = dynamic_cast(mFloaterHandle.get()); + if( floaterp ) + { + floaterp->setCanApply(can_preview, can_apply); + } +} + void LLTextureCtrl::setVisible( BOOL visible ) { if( !visible ) @@ -1341,6 +1410,12 @@ void LLTextureCtrl::showPicker(BOOL take_focus) mFloaterHandle = floaterp->getHandle(); + LLFloaterTexturePicker* texture_floaterp = dynamic_cast(floaterp); + if (texture_floaterp && mOnTextureSelectedCallback) + { + texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback); + } + gFloaterView->getParentFloater(this)->addDependentFloater(floaterp); floaterp->open(); /* Flawfinder: ignore */ } @@ -1395,6 +1470,10 @@ void LLTextureCtrl::onFloaterClose() if (floaterp) { + if (mOnCloseCallback) + { + mOnCloseCallback(this,LLSD()); + } floaterp->setOwner(NULL); mLastFloaterLeftTop.set( floaterp->getRect().mLeft, floaterp->getRect().mTop ); } @@ -1466,6 +1545,16 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id) // tag: vaa emerald local_asset_browser [end] +void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb) +{ + mOnTextureSelectedCallback = cb; + LLFloaterTexturePicker* floaterp = dynamic_cast(mFloaterHandle.get()); + if (floaterp) + { + floaterp->setTextureSelectedCallback(cb); + } +} + void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) { if( mImageAssetID != asset_id ) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 27afeba3d..718aa1106 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -48,6 +48,7 @@ class LLViewerFetchedTexture; // used for setting drag & drop callbacks. typedef boost::function drag_n_drop_callback; +typedef boost::function texture_selected_callback; ////////////////////////////////////////////////////////////////////////////////////////// @@ -79,7 +80,6 @@ public: static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, @@ -124,12 +124,17 @@ public: const std::string& getDefaultImageName() const { return mDefaultImageName; } + void setBlankImageAssetID(const LLUUID& id); + const LLUUID& getBlankImageAssetID() const; + void setFallbackImageName( const std::string& name ) { mFallbackImageName = name; } const std::string& getFallbackImageName() const { return mFallbackImageName; } void setCaption(const std::string& caption); void setCanApplyImmediately(BOOL b); + void setCanApply(bool can_preview, bool can_apply); + void setImmediateFilterPermMask(PermissionMask mask) { mImmediateFilterPermMask = mask; } void setDnDFilterPermMask(PermissionMask mask) @@ -155,11 +160,18 @@ public: void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; } void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; } - + void setOnCloseCallback(commit_callback_t cb) { mOnCloseCallback = cb; } void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; } + /* + * callback for changing texture selection in inventory list of texture floater + */ + void setOnTextureSelectedCallback(texture_selected_callback cb); + void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder); + LLViewerFetchedTexture* getTexture() { return mTexturep; } + static void handleClickOpenTexture(void* userdata); static void handleClickCopyAssetID(void* userdata); @@ -172,6 +184,8 @@ private: drag_n_drop_callback mDropCallback; commit_callback_t mOnCancelCallback; commit_callback_t mOnSelectCallback; + commit_callback_t mOnCloseCallback; + texture_selected_callback mOnTextureSelectedCallback; LLPointer mTexturep; LLColor4 mBorderColor; LLUUID mImageItemID; diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 2a79e0c32..3f755dbf2 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -2,31 +2,25 @@ * @file lltoolcomp.cpp * @brief Composite tools * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -49,6 +43,7 @@ #include "lltoolmgr.h" #include "lltoolselectrect.h" #include "lltoolplacer.h" +#include "llviewercamera.h" // #include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerwindow.h" @@ -57,7 +52,7 @@ #include "llfloatertools.h" #include "qtoolalign.h" #include "llviewercontrol.h" -#include "llviewercamera.h" + const S32 BUTTON_HEIGHT = 16; const S32 BUTTON_WIDTH_SMALL = 32; @@ -659,6 +654,7 @@ void LLToolCompRotate::render() LLToolCompGun::LLToolCompGun() : LLToolComposite(std::string("Mouselook")) + , mRightMouseButton(false), mMenuShown(false), mTimerFOV(), mOriginalFOV(), mStartFOV(), mTargetFOV() // { mGun = new LLToolGun(this); mGrab = new LLToolGrab(this); @@ -666,8 +662,11 @@ LLToolCompGun::LLToolCompGun() setCurrentTool(mGun); mDefault = mGun; -} + // + mTimerFOV.stop(); + // +} LLToolCompGun::~LLToolCompGun() { @@ -751,24 +750,9 @@ BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask) return LLToolGrab::getInstance()->handleDoubleClick(x, y, mask); } - +/* Singu Note: Moved to bottom, upstream is Exodus BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - /* JC - suppress context menu 8/29/2002 - - // On right mouse, go through some convoluted steps to - // make the build menu appear. - setCurrentTool( (LLTool*) mNull ); - - // This should return FALSE, meaning the context menu will - // be shown. - return FALSE; - */ - - // Returning true will suppress the context menu - return TRUE; -} - +*/ BOOL LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask) { @@ -799,27 +783,93 @@ void LLToolCompGun::handleDeselect() setMouseCapture(FALSE); } +// + +BOOL LLToolCompGun::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ + // Singu Note: Beware the alt-click menu + if (mRightMouseButton) + { + mRightMouseButton = false; + + mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV(); + mTargetFOV = mOriginalFOV; + mTimerFOV.start(); + } + + if (mMenuShown) + { + mMenuShown = false; + return LLToolComposite::handleRightMouseUp(x, y, mask); + } + + return TRUE; +} + +BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + // Singu Note: Beware the alt-click menu + if (gSavedSettings.getBOOL("LiruMouselookMenu") && mask & MASK_ALT) + { + mMenuShown = true; + return false; + } + + mRightMouseButton = true; + + if(!mTimerFOV.getStarted()) + { + mStartFOV = LLViewerCamera::getInstance()->getAndSaveDefaultFOV(); + mOriginalFOV = mStartFOV; + } + else mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV(); + + mTargetFOV = gSavedSettings.getF32("zmm_mlfov"); + mTimerFOV.start(); + + return TRUE; +} BOOL LLToolCompGun::handleScrollWheel(S32 x, S32 y, S32 clicks) { - //::MOYMOD:: - if(gSavedSettings.getBOOL("zmm_isinml") == 1) + if (mRightMouseButton) { - if(clicks > 0) - { - gSavedSettings.setF32("zmm_mlfov", gSavedSettings.getF32("zmm_mlfov") / 1.1); - } - else if(clicks < 0) - { - gSavedSettings.setF32("zmm_mlfov", gSavedSettings.getF32("zmm_mlfov") * 1.1); - } - LLViewerCamera::getInstance()->setDefaultFOV(gSavedSettings.getF32("zmm_deffov") / gSavedSettings.getF32("zmm_mlfov")); - return TRUE; - } - if (clicks > 0) - { - gAgentCamera.changeCameraToDefault(); + mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV(); + gSavedSettings.setF32( + "zmm_mlfov", + mTargetFOV = clicks > 0 ? + llclamp(mTargetFOV += (0.05f * clicks), 0.1f, 3.0f) : + llclamp(mTargetFOV -= (0.05f * -clicks), 0.1f, 3.0f) + ); + + mTimerFOV.start(); } + else if (clicks > 0) gAgentCamera.changeCameraToDefault(); + return TRUE; } + +// Zoom related stuff... + +void LLToolCompGun::draw() +{ + if (mTimerFOV.getStarted()) + { + if (!LLViewerCamera::getInstance()->mSavedFOVLoaded && mStartFOV != mTargetFOV) + { + F32 timer = mTimerFOV.getElapsedTimeF32(); + + if (timer > 0.15f) + { + LLViewerCamera::getInstance()->setDefaultFOV(mTargetFOV); + mTimerFOV.stop(); + } + else LLViewerCamera::getInstance()->setDefaultFOV(lerp(mStartFOV, mTargetFOV, timer * 6.66f)); + } + else mTimerFOV.stop(); + } + LLToolComposite::draw(); // Singu Note: We call parent here, instead of being clueless and adding to LLViewerWindow::draw for crosshairs and such +} + +// diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h index 81ed0ba8e..07cf2815b 100644 --- a/indra/newview/lltoolcomp.h +++ b/indra/newview/lltoolcomp.h @@ -2,31 +2,25 @@ * @file lltoolcomp.h * @brief Composite tools * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -219,10 +213,13 @@ public: LLToolCompGun(); virtual ~LLToolCompGun(); + virtual void draw(); // + // Overridden from LLToolComposite virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); @@ -235,6 +232,13 @@ protected: LLToolGun* mGun; LLToolGrab* mGrab; LLTool* mNull; + + // +private: + bool mRightMouseButton, mMenuShown; + LLTimer mTimerFOV; + F32 mOriginalFOV, mStartFOV, mTargetFOV; + // }; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index a97711e4e..3b44f27a3 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -31,26 +31,19 @@ */ #include "llviewerprecompiledheaders.h" - -#include "message.h" #include "lltooldraganddrop.h" +// library headers #include "llnotificationsutil.h" - -#include "llinstantmessage.h" -#include "lldir.h" - +// project headers #include "llagent.h" #include "llagentcamera.h" #include "llagentwearables.h" #include "llappearancemgr.h" #include "lldictionary.h" -#include "llviewercontrol.h" #include "llfirstuse.h" -#include "llfloater.h" #include "llfloaterinventory.h" #include "llfloatertools.h" -#include "llfocusmgr.h" #include "llgesturemgr.h" #include "llgiveinventory.h" #include "llhudmanager.h" @@ -66,7 +59,6 @@ #include "llselectmgr.h" #include "lltoolmgr.h" #include "lltrans.h" -#include "llui.h" #include "llviewertexturelist.h" #include "llviewerinventory.h" #include "llviewerobject.h" @@ -77,14 +69,14 @@ #include "llvoavatarself.h" #include "llvolume.h" #include "llworld.h" -#include "object_flags.h" +#include "llpanelface.h" // #include "llappviewer.h" // System Folders #include "llparcel.h" // always rez #include "llviewerparcelmgr.h" // always rez // -// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] @@ -388,9 +380,12 @@ void LLToolDragAndDrop::setDragStart(S32 x, S32 y) BOOL LLToolDragAndDrop::isOverThreshold(S32 x,S32 y) { - const S32 MIN_MANHATTAN_DIST = 3; - S32 manhattan_dist = llabs( x - mDragStartX ) + llabs( y - mDragStartY ); - return manhattan_dist >= MIN_MANHATTAN_DIST; + static LLCachedControl drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold"); + + S32 mouse_delta_x = x - mDragStartX; + S32 mouse_delta_y = y - mDragStartY; + + return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > drag_and_drop_threshold * drag_and_drop_threshold; } void LLToolDragAndDrop::beginDrag(EDragAndDropType type, @@ -1162,10 +1157,56 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, // update viewer side image in anticipation of update from simulator //LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); - //hit_obj->setTEImage(hit_face, image); - hit_obj->setTETexture(hit_face, asset_id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, - // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, - // which we don't want. + + LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL; + + LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + + if (gFloaterTools->getVisible() && panel_face) + { + switch (LLSelectMgr::getInstance()->getTextureChannel()) + { + case 0: + default: + { + //hit_obj->setTEImage(hit_face, image); + hit_obj->setTETexture(hit_face, asset_id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. + } + break; + + case 1: + { + LLMaterialPtr old_mat = tep->getMaterialParams(); + LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); + new_mat->setNormalID(asset_id); + tep->setMaterialParams(new_mat); + hit_obj->setTENormalMap(hit_face, asset_id); + LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); + } + break; + + case 2: + { + LLMaterialPtr old_mat = tep->getMaterialParams(); + LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); + new_mat->setSpecularID(asset_id); + tep->setMaterialParams(new_mat); + hit_obj->setTESpecularMap(hit_face, asset_id); + LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); + } + break; + } + } + else + { + //hit_obj->setTEImage(hit_face, image); + hit_obj->setTETexture(hit_face, asset_id); //Singu note: setTETexture will allow the real id to be passed to LLPrimitive::setTETexture, + // even if it's null. setTEImage would actually pass down IMG_DEFAULT under such a case, + // which we don't want. + } + dialog_refresh_all(); // send the update to the simulator @@ -1619,6 +1660,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ case DAD_ANIMATION: case DAD_GESTURE: case DAD_CALLINGCARD: + case DAD_MESH: { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) @@ -2353,7 +2395,7 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory( } } - // if every item is accepted, go ahead and send it on. + // If every item is accepted, send it on if(drop && (ACCEPT_YES_COPY_SINGLE <= rv)) { uuid_vec_t ids; @@ -2595,7 +2637,12 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory( { item = NULL; cat = NULL; - if(mCargoIDs.empty()) return NULL; + + if (mCargoIDs.empty()) + { + return NULL; + } + if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) { // The object should be in user inventory. diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index 716edd7dd..92e525882 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -141,8 +141,6 @@ void LLToolMgr::initTools() gBasicToolset->addTool( LLToolCompInspect::getInstance() ); gFaceEditToolset->addTool( LLToolCamera::getInstance() ); - // In case focus was lost before we got here - clearSavedTool(); // On startup, use "select" tool setCurrentToolset(gBasicToolset); @@ -283,24 +281,7 @@ bool LLToolMgr::canEdit() void LLToolMgr::toggleBuildMode() { - if (inBuildMode()) - { - if (gSavedSettings.getBOOL("EditCameraMovement")) - { - // just reset the view, will pull us out of edit mode - handle_reset_view(); - } - else - { - // manually disable edit mode, but do not affect the camera - gAgentCamera.resetView(false); - gFloaterTools->close(); - gViewerWindow->showCursor(); - } - // avoid spurious avatar movements pulling out of edit mode - LLViewerJoystick::getInstance()->setNeedsReset(); - } - else + if (!inBuildMode()) { ECameraMode camMode = gAgentCamera.getCameraMode(); if (CAMERA_MODE_MOUSELOOK == camMode || CAMERA_MODE_CUSTOMIZE_AVATAR == camMode) @@ -350,6 +331,24 @@ void LLToolMgr::toggleBuildMode() LLViewerJoystick::getInstance()->setNeedsReset(); } + else + { + if (gSavedSettings.getBOOL("EditCameraMovement")) + { + // just reset the view, will pull us out of edit mode + handle_reset_view(); + } + else + { + // manually disable edit mode, but do not affect the camera + gAgentCamera.resetView(false); + gFloaterTools->close(); + gViewerWindow->showCursor(); + } + // avoid spurious avatar movements pulling out of edit mode + LLViewerJoystick::getInstance()->setNeedsReset(); + } + } bool LLToolMgr::inBuildMode() diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index e3dce440d..fa74444ff 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1092,9 +1092,6 @@ BOOL LLToolPie::handleRightClickPick() // didn't click in any UI object, so must have clicked in the world LLViewerObject *object = mPick.getObject(); - LLViewerObject *parent = NULL; - if(object) - parent = object->getRootEdit(); // Can't ignore children here. LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE); @@ -1104,7 +1101,7 @@ BOOL LLToolPie::handleRightClickPick() { LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( mPick.mPosGlobal ); gMenuHolder->setParcelSelection(selection); - gPieLand->show(x, y, true); + gPieLand->show(x, y); showVisualContextMenuEffect(); @@ -1118,7 +1115,7 @@ BOOL LLToolPie::handleRightClickPick() return TRUE ; } - gPieSelf->show(x, y, true); + gPieSelf->show(x, y); } else if (object) { @@ -1162,11 +1159,11 @@ BOOL LLToolPie::handleRightClickPick() // [/RLVa:KB] /*if (is_other_attachment) { - gPieAttachmentOther->show(x, y, true); + gPieAttachmentOther->show(x, y); } else*/ { - gPieAvatar->show(x, y, true); + gPieAvatar->show(x, y); } // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l } @@ -1178,7 +1175,7 @@ BOOL LLToolPie::handleRightClickPick() } else if (object->isAttachment()) { - gPieAttachment->show(x, y, true); + gPieAttachment->show(x, y); } else { @@ -1207,7 +1204,7 @@ BOOL LLToolPie::handleRightClickPick() { // [/RLVa:KB] gMenuHolder->childSetText("Object Mute", mute_msg); - gPieObject->show(x, y, true); + gPieObject->show(x, y); showVisualContextMenuEffect(); // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.el) | Modified: RLVa-1.1.0l diff --git a/indra/newview/lluserauth.cpp b/indra/newview/lluserauth.cpp index a0791989e..8c2d359a1 100644 --- a/indra/newview/lluserauth.cpp +++ b/indra/newview/lluserauth.cpp @@ -217,8 +217,21 @@ void LLUserAuth::authenticate( XMLRPC_VectorAppendString(params, "last", lastname.c_str(), 0); XMLRPC_VectorAppendString(params, "passwd", dpasswd.c_str(), 0); XMLRPC_VectorAppendString(params, "start", start.c_str(), 0); - XMLRPC_VectorAppendString(params, "version", gCurrentVersion.c_str(), 0); // Includes channel name - XMLRPC_VectorAppendString(params, "channel", gVersionChannel, 0); + XMLRPC_VectorAppendString(params, "version", llformat("%d.%d.%d.%d", gVersionMajor, gVersionMinor, gVersionPatch, gVersionBuild).c_str(), 0); + // Singu Note: At the request of Linden Lab we change channel sent to the login server in the following way: + // * If channel is "Singularity" we change it to "Singularity Release", due to their statistics system + // not being able to distinguish just the release version + // * We append "64" to channel name on 64-bit for systems for the LL stats system to be able to produce independent + // crash statistics depending on the architecture + std::string chan(gVersionChannel); + if (chan == "Singularity") + { + chan += " Release"; + } +#if defined(_WIN64) || defined(__x86_64__) + chan += " 64"; +#endif + XMLRPC_VectorAppendString(params, "channel", chan.c_str(), 0); XMLRPC_VectorAppendString(params, "platform", PLATFORM_STRING, 0); XMLRPC_VectorAppendString(params, "mac", hashed_mac.c_str(), 0); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 9266dc434..b70183fd4 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -2,31 +2,25 @@ * @file llviewercamera.cpp * @brief LLViewerCamera class implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -113,6 +107,7 @@ LLViewerCamera::LLViewerCamera() : LLCamera() { calcProjection(getFar()); mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; + mSavedFOVDefault = DEFAULT_FIELD_OF_VIEW; // mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); mPixelMeterRatio = 0.f; mScreenPixelArea = 0; @@ -927,6 +922,15 @@ void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); } +// +void LLViewerCamera::loadDefaultFOV() +{ + setView(mSavedFOVDefault); + mSavedFOVLoaded = true; + mCameraFOVDefault = mSavedFOVDefault; + mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); +} +// // static void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value) diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 82d88bc3d..d9ac2af30 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -2,31 +2,25 @@ * @file llviewercamera.h * @brief LLViewerCamera class header file * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -118,6 +112,11 @@ public: void setDefaultFOV(F32 fov) ; F32 getDefaultFOV() { return mCameraFOVDefault; } + bool mSavedFOVLoaded; // + F32 getAndSaveDefaultFOV() { mSavedFOVLoaded = false; return mSavedFOVDefault = mCameraFOVDefault; } // + void setAndSaveDefaultFOV(F32 fov) { setDefaultFOV(mSavedFOVDefault = fov); } // + void loadDefaultFOV(); // + BOOL cameraUnderWater() const; const LLVector3 &getPointOfInterest() { return mLastPointOfInterest; } @@ -141,6 +140,7 @@ protected: mutable LLMatrix4 mProjectionMatrix; // Cache of perspective matrix mutable LLMatrix4 mModelviewMatrix; F32 mCameraFOVDefault; + F32 mSavedFOVDefault; // F32 mCosHalfCameraFOV; LLVector3 mLastPointOfInterest; F32 mPixelMeterRatio; // Divide by distance from camera to get pixels per meter at that distance. diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index de52941d1..7194711a6 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -655,13 +655,16 @@ bool LLViewerInventoryCategory::fetch() { llwarns << "agent region is null" << llendl; } - if (!url.empty()) //Capability found. Build up LLSD and use it. + if (!url.empty() && gSavedSettings.getBOOL("UseHTTPInventory")) //Capability found and HTTP inventory enabled. Build up LLSD and use it. { LLInventoryModelBackgroundFetch::instance().start(mUUID, false); } else - { //Deprecated, but if we don't have a capability, use the old system. - llinfos << "FetchInventoryDescendents2 capability not found. Using deprecated UDP message." << llendl; + { //We don't have a capability or the use of HTTP inventory is disabled, use the old system. + if (gSavedSettings.getBOOL("UseHTTPInventory")) + { + llinfos << "FetchInventoryDescendents2 capability not found. Using UDP message." << llendl; + } LLMessageSystem* msg = gMessageSystem; msg->newMessage("FetchInventoryDescendents"); msg->nextBlock("AgentData"); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 6cd1e611f..e9211231f 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1551,16 +1551,22 @@ void LLViewerMedia::proxyWindowClosed(const std::string &uuid) // static void LLViewerMedia::createSpareBrowserMediaSource() { + static bool failedLoading = false; + // If we don't have a spare browser media source, create one. // However, if PluginAttachDebuggerToPlugins is set then don't spawn a spare // SLPlugin process in order to not be confused by an unrelated gdb terminal // popping up at the moment we start a media plugin. - if (!sSpareBrowserMediaSource && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")) + if (!failedLoading && !sSpareBrowserMediaSource && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")) { // The null owner will keep the browser plugin from fully initializing // (specifically, it keeps LLPluginClassMedia from negotiating a size change, // which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color) sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType("text/html", NULL, 0, 0); + if (!sSpareBrowserMediaSource) + { + failedLoading = true; + } } } @@ -1916,10 +1922,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ } LL_WARNS_ONCE("Plugin") << "plugin initialization failed for mime type: " << media_type << LL_ENDL; + /* There is a reason why ^^ is ONCE LLSD args; args["MIME_TYPE"] = media_type; LLNotificationsUtil::add("NoPlugin", args); - + */ return NULL; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 787a345c8..48fe25ce7 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -189,6 +189,7 @@ #include "llvovolume.h" #include "hippogridmanager.h" +#include "wlfPanel_AdvSettings.h" void toggle_search_floater(); @@ -248,11 +249,11 @@ LLMenuGL *gPopupMenuView = NULL; LLMenuBarGL *gLoginMenuBarView = NULL; // Pie menus -LLPieMenu *gPieSelf = NULL; -LLPieMenu *gPieAvatar = NULL; -LLPieMenu *gPieObject = NULL; -LLPieMenu *gPieAttachment = NULL; -LLPieMenu *gPieLand = NULL; +LLContextMenu *gPieSelf = NULL; +LLContextMenu *gPieAvatar = NULL; +LLContextMenu *gPieObject = NULL; +LLContextMenu *gPieAttachment = NULL; +LLContextMenu *gPieLand = NULL; // local constants const std::string CLIENT_MENU_NAME("Advanced"); @@ -265,13 +266,13 @@ LLMenuGL* gAttachSubMenu = NULL; LLMenuGL* gDetachSubMenu = NULL; LLMenuGL* gTakeOffClothes = NULL; LLMenuGL* gMeshesAndMorphsMenu = NULL; -LLPieMenu* gPieRate = NULL; -LLPieMenu* gAttachScreenPieMenu = NULL; -LLPieMenu* gAttachPieMenu = NULL; -LLPieMenu* gAttachBodyPartPieMenus[8]; -LLPieMenu* gDetachPieMenu = NULL; -LLPieMenu* gDetachScreenPieMenu = NULL; -LLPieMenu* gDetachBodyPartPieMenus[8]; +LLContextMenu* gPieRate = NULL; +LLContextMenu* gAttachScreenPieMenu = NULL; +LLContextMenu* gAttachPieMenu = NULL; +LLContextMenu* gAttachBodyPartPieMenus[8]; +LLContextMenu* gDetachPieMenu = NULL; +LLContextMenu* gDetachScreenPieMenu = NULL; +LLContextMenu* gDetachBodyPartPieMenus[8]; LLMenuItemCallGL* gAFKMenu = NULL; LLMenuItemCallGL* gBusyMenu = NULL; @@ -601,6 +602,42 @@ void set_underclothes_menu_options() static std::vector > sMenus; +void build_pie_menus() +{ + if (gPieSelf) delete gPieSelf; + gPieSelf = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_self.xml", gMenuHolder); + + // TomY TODO: what shall we do about these? + gDetachScreenPieMenu = gMenuHolder->getChild("Object Detach HUD", true); + gDetachPieMenu = gMenuHolder->getChild("Object Detach", true); + + if (gPieAvatar) delete gPieAvatar; + gPieAvatar = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_avatar.xml", gMenuHolder); + + if (gPieObject) delete gPieObject; + gPieObject = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_object.xml", gMenuHolder); + + gAttachScreenPieMenu = gMenuHolder->getChild("Object Attach HUD"); + gAttachPieMenu = gMenuHolder->getChild("Object Attach"); + gPieRate = gMenuHolder->getChild("Rate Menu"); + + if (gPieAttachment) delete gPieAttachment; + gPieAttachment = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_attachment.xml", gMenuHolder); + + if (gPieLand) delete gPieLand; + gPieLand = LLUICtrlFactory::getInstance()->buildContextMenu("menu_pie_land.xml", gMenuHolder); +} + +void rebuild_context_menus() +{ + llassert_always(gMenuHolder); + if (!gMenuHolder) return; // This should never happen, if it does, don't do anything, menus haven't been built yet or were destroyed. + gMenuHolder->hideMenus(); + build_pie_menus(); + if (!gAgentAvatarp) return; // The agent's avatar isn't here yet, don't bother with the dynamic attach/detach submenus. + gAgentAvatarp->buildContextMenus(); +} + void init_menus() { S32 top = gViewerWindow->getRootView()->getRect().getHeight(); @@ -632,36 +669,15 @@ void init_menus() /// /// Pie menus /// - gPieSelf = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_self.xml", gMenuHolder); + build_pie_menus(); + gSavedSettings.getControl("LiruUseContextMenus")->getSignal()->connect(boost::bind(rebuild_context_menus)); - // TomY TODO: what shall we do about these? - gDetachScreenPieMenu = gMenuHolder->getChild("Object Detach HUD", true); - gDetachPieMenu = gMenuHolder->getChild("Object Detach", true); - - gPieAvatar = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_avatar.xml", gMenuHolder); - - gPieObject = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_object.xml", gMenuHolder); - - gAttachScreenPieMenu = gMenuHolder->getChild("Object Attach HUD"); - gAttachPieMenu = gMenuHolder->getChild("Object Attach"); - gPieRate = gMenuHolder->getChild("Rate Menu"); - - gPieAttachment = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_attachment.xml", gMenuHolder); - - gPieLand = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_land.xml", gMenuHolder); /// /// set up the colors /// LLColor4 color; - LLColor4 pie_color = gColors.getColor("PieMenuBgColor"); - gPieSelf->setBackgroundColor( pie_color ); - gPieAvatar->setBackgroundColor( pie_color ); - gPieObject->setBackgroundColor( pie_color ); - gPieAttachment->setBackgroundColor( pie_color ); - gPieLand->setBackgroundColor( pie_color ); - color = gColors.getColor( "MenuPopupBgColor" ); gPopupMenuView->setBackgroundColor( color ); @@ -748,6 +764,8 @@ void init_menus() menu = new LLMenuGL(CLIENT_MENU_NAME); menu->setCanTearOff(FALSE); menu->addChild(new LLMenuItemCallGL("Debug Settings...", handle_singleton_toggle, NULL, NULL)); + // Debugging view for unified notifications: CTRL-SHIFT-5 + menu->addChild(new LLMenuItemCallGL("Notifications Console...", handle_show_notifications_console, NULL, NULL, '5', MASK_CONTROL|MASK_SHIFT)); gLoginMenuBarView->addChild(menu); menu->updateParent(LLMenuGL::sMenuContainer); @@ -4120,8 +4138,19 @@ void reset_view_final( BOOL proceed ) } gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW); + if (wlfPanel_AdvSettings::instanceExists()) // Fix up the buttons on the wlf panel to match the preset switch + { + wlfPanel_AdvSettings& inst(wlfPanel_AdvSettings::instance()); + if (inst.isExpanded()) + { + inst.getChildView("Rear")->setValue(true); + inst.getChildView("Front")->setValue(false); + inst.getChildView("Group")->setValue(false); + } + } gAgentCamera.resetView(TRUE, TRUE); gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); + gSavedSettings.setBOOL("SinguMotionResetsCamera", true); if(gAgentCamera.cameraCustomizeAvatar() && LLFloaterCustomize::instanceExists()) LLFloaterCustomize::getInstance()->close(); @@ -5536,7 +5565,7 @@ class LLEditDelete : public view_listener_t // When deleting an object we may not actually be done // Keep selection so we know what to delete when confirmation is needed about the delete - gPieObject->hide(TRUE); + gPieObject->hide(); return true; } }; @@ -5656,7 +5685,7 @@ void handle_object_delete() // When deleting an object we may not actually be done // Keep selection so we know what to delete when confirmation is needed about the delete - gPieObject->hide(TRUE); + gPieObject->hide(); return; } diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 6d3c2947f..b45cf7633 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -167,24 +167,24 @@ extern LLViewerMenuHolderGL* gMenuHolder; extern LLMenuBarGL* gLoginMenuBarView; // Pie menus -extern LLPieMenu *gPieSelf; -extern LLPieMenu *gPieAvatar; -extern LLPieMenu *gPieObject; -extern LLPieMenu *gPieAttachment; -extern LLPieMenu *gPieLand; -extern LLPieMenu *gPieRate; +extern LLContextMenu *gPieSelf; +extern LLContextMenu *gPieAvatar; +extern LLContextMenu *gPieObject; +extern LLContextMenu *gPieAttachment; +extern LLContextMenu *gPieLand; +extern LLContextMenu *gPieRate; // Needed to build menus when attachment site list available extern LLMenuGL* gAttachSubMenu; extern LLMenuGL* gDetachSubMenu; extern LLMenuGL* gTakeOffClothes; extern LLMenuGL* gMeshesAndMorphsMenu; -extern LLPieMenu* gAttachScreenPieMenu; -extern LLPieMenu* gDetachScreenPieMenu; -extern LLPieMenu* gAttachPieMenu; -extern LLPieMenu* gDetachPieMenu; -extern LLPieMenu* gAttachBodyPartPieMenus[8]; -extern LLPieMenu* gDetachBodyPartPieMenus[8]; +extern LLContextMenu* gAttachScreenPieMenu; +extern LLContextMenu* gDetachScreenPieMenu; +extern LLContextMenu* gAttachPieMenu; +extern LLContextMenu* gDetachPieMenu; +extern LLContextMenu* gAttachBodyPartPieMenus[8]; +extern LLContextMenu* gDetachBodyPartPieMenus[8]; extern LLMenuItemCallGL* gAFKMenu; extern LLMenuItemCallGL* gBusyMenu; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index fb0264b56..b1523682d 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4458,7 +4458,9 @@ void process_teleport_finish(LLMessageSystem* msg, void**) // Aurora Sim U32 region_size_x = 256; msg->getU32Fast(_PREHASH_Info, _PREHASH_RegionSizeX, region_size_x); - LLWorld::getInstance()->setRegionWidth(region_size_x); + U32 region_size_y = 256; + msg->getU32Fast(_PREHASH_Info, _PREHASH_RegionSizeY, region_size_y); + LLWorld::getInstance()->setRegionSize(region_size_x, region_size_y); // Aurora Sim LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host); @@ -4788,7 +4790,9 @@ void process_crossed_region(LLMessageSystem* msg, void**) // Aurora Sim U32 region_size_x = 256; msg->getU32(_PREHASH_RegionData, _PREHASH_RegionSizeX, region_size_x); - LLWorld::getInstance()->setRegionWidth(region_size_x); + U32 region_size_y = 256; + msg->getU32(_PREHASH_RegionData, _PREHASH_RegionSizeY, region_size_y); + LLWorld::getInstance()->setRegionSize(region_size_x, region_size_y); // Aurora Sim LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host); regionp->setSeedCapability(seedCap); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 161ac8f91..0754d1d2e 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -297,6 +297,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mRegionFlags( REGION_FLAGS_DEFAULT ), mRegionProtocols( 0 ), mSimAccess( SIM_ACCESS_MIN ), + mLastSimAccess( 0 ), + mSimAccessString( "unknown" ), mBillableFactor(1.0), mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT), mCentralBakeVersion(0), @@ -599,9 +601,15 @@ BOOL LLViewerRegion::canManageEstate() const || gAgent.getID() == getOwner(); } -const std::string LLViewerRegion::getSimAccessString() const +std::string const& LLViewerRegion::getSimAccessString() { - return accessToString(mSimAccess); + // Singu: added a cache because this is called every frame. + if (mLastSimAccess != mSimAccess) + { + mSimAccessString = accessToString(mSimAccess); + mLastSimAccess = mSimAccess; + } + return mSimAccessString; } std::string LLViewerRegion::getLocalizedSimProductName() const @@ -2134,4 +2142,4 @@ U32 LLViewerRegion::getMaxMaterialsPerTransaction() const max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger(); } return max_entries; -} \ No newline at end of file +} diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c2cc7fe39..f5d2d2eae 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -204,8 +204,8 @@ public: void setSimAccess(U8 sim_access) { mSimAccess = sim_access; } U8 getSimAccess() const { return mSimAccess; } - const std::string getSimAccessString() const; - + std::string const& getSimAccessString(); // Singu note: return reference to mSimAccessString. + // Homestead-related getters; there are no setters as nobody should be // setting them other than the individual message handler which is a member S32 getSimClassID() const { return mClassID; } @@ -430,6 +430,8 @@ private: U64 mRegionFlags; // includes damage flags U64 mRegionProtocols; // protocols supported by this region U8 mSimAccess; + U8 mLastSimAccess; // Singularity extension. + std::string mSimAccessString; // Singularity extension. F32 mBillableFactor; U32 mMaxTasks; // max prim count F32 mCameraDistanceSquared; // updated once per frame diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 9704fe2cb..57e63be70 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1644,15 +1644,8 @@ LLView* LLViewerTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlF LLFontGL* font = LLView::selectFont(node); - // std::string text = node->getValue(); std::string text = node->getTextContents().substr(0, max_text_length - 1); - if (text.size() > max_text_length) - { - // Erase everything from max_text_length on. - text.erase(max_text_length); - } - LLViewerTextEditor* text_editor = new LLViewerTextEditor("text_editor", rect, max_text_length, diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index e86dbfd21..8c52fe762 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1219,6 +1219,12 @@ S32 LLViewerTextureList::getMinVideoRamSetting() // Returns max setting for TextureMemory (in MB) S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) { +#if LL_LINUX + if (gGLManager.mIsIntel && gGLManager.mGLVersion >= 3.f && !gGLManager.mVRAM) + { + gGLManager.mVRAM = 512; + } +#endif S32 max_texmem; if (gGLManager.mVRAM != 0) { diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index bdd03c0eb..eca1c0615 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -40,6 +40,7 @@ #include "llviewerregion.h" #include "llinventoryobserver.h" #include "llinventoryfunctions.h" +#include "aixmllindengenepool.h" using namespace LLAvatarAppearanceDefines; @@ -134,32 +135,18 @@ LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_st return result; } -extern void dump_visual_param(LLAPRFile& file, LLVisualParam const* viewer_param, F32 value); - -void LLViewerWearable::archetypeExport(LLAPRFile& file) const +AIArchetype LLViewerWearable::getArchetype(void) const { - apr_file_t* fp = file.getFileHandle(); - - std::string path; - append_path_short(mItemID, path); - apr_file_printf(fp, " \n", - LLXMLNode::escapeXML(path).c_str(), - LLXMLNode::escapeXML(mName).c_str(), - LLXMLNode::escapeXML(mDescription).c_str()); - + AIArchetype archetype(this); for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter) { - LLVisualParam const* param = iter->second; - dump_visual_param(file, param, param->getWeight()); + archetype.add(AIVisualParamIDValuePair(iter->second)); } for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter) { - S32 te = iter->first; - LLUUID const& image_id = iter->second->getID(); - apr_file_printf(fp, " \n", te, image_id.asString().c_str()); + archetype.add(AITextureIDUUIDPair(iter->first, iter->second->getID())); } - - apr_file_printf(fp, "\n"); + return archetype; } // Avatar parameter and texture definitions can change over time. @@ -698,7 +685,7 @@ std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w) //w.mSaleInfo s << " Params:" << "\n"; - for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin(); + for (LLViewerWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin(); iter != w.mVisualParamIndexMap.end(); ++iter) { S32 param_id = iter->first; diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h index 660594d26..fbf4c87a0 100644 --- a/indra/newview/llviewerwearable.h +++ b/indra/newview/llviewerwearable.h @@ -29,6 +29,7 @@ #include "llwearable.h" #include "llavatarappearancedefines.h" +#include "aixmllindengenepool.h" class LLVOAvatar; class LLAPRFile; @@ -67,8 +68,9 @@ public: /*virtual*/ EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp ); - void archetypeExport(LLAPRFile& file) const; - + // Singu extension. + AIArchetype getArchetype(void) const; + void setParamsToDefaults(); void setTexturesToDefaults(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2a03092e1..4f2e5c931 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1016,18 +1016,6 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { - //From Phoenix - // Singu TODO: Change these from debug settings to externs? - gSavedSettings.setBOOL("zmm_rightmousedown", true); - if (gAgentCamera.cameraMouselook() && !gSavedSettings.getBOOL("zmm_isinml")) - { - llinfos << "zmmisinml set to true" << llendl; - gSavedSettings.setBOOL("zmm_isinml", true); - F32 deffov = LLViewerCamera::getInstance()->getDefaultFOV(); - gSavedSettings.setF32("zmm_deffov", deffov); - LLViewerCamera::getInstance()->setDefaultFOV(deffov/gSavedSettings.getF32("zmm_mlfov")); - } - S32 x = pos.mX; S32 y = pos.mY; x = llround((F32)x / mDisplayScale.mV[VX]); @@ -1056,14 +1044,6 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { - gSavedSettings.setBOOL("zmm_rightmousedown", false); - if(gSavedSettings.getBOOL("zmm_isinml")==1) - { - llinfos << "zmmisinml set to false" << llendl; - gSavedSettings.setBOOL("zmm_isinml",0); - LLViewerCamera::getInstance()->setDefaultFOV(gSavedSettings.getF32("zmm_deffov")); - } - BOOL down = FALSE; return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down); } @@ -2714,12 +2694,9 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } // HACK look for UI editing keys - if (LLView::sEditingUI) + if (LLView::sEditingUI && LLFloaterEditUI::processKeystroke(key, mask)) { - if (LLFloaterEditUI::processKeystroke(key, mask)) - { - return TRUE; - } + return TRUE; } // Explicit hack for debug menu. @@ -2730,32 +2707,6 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) toggle_debug_menus(NULL); } - // Explicit hack for debug menu. - //Singu note: We do not use the ForceShowGrid setting. Grid selection should always be visible. - /*if ((mask == (MASK_SHIFT | MASK_CONTROL)) && - ('G' == key || 'g' == key)) - { - if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page - { - BOOL visible = ! gSavedSettings.getBOOL("ForceShowGrid"); - gSavedSettings.setBOOL("ForceShowGrid", visible); - - // Initialize visibility (and don't force visibility - use prefs) - LLPanelLogin::updateLocationSelectorsVisibility(); - } - }*/ - - // Debugging view for unified notifications: CTRL-SHIFT-5 - // *FIXME: Having this special-cased right here (just so this can be invoked from the login screen) sucks. - if ((MASK_SHIFT & mask) - && (!(MASK_ALT & mask)) - && (MASK_CONTROL & mask) - && ('5' == key)) - { - LLFloaterNotificationConsole::showInstance(); - return TRUE; - } - // handle shift-escape key (reset camera view) if (key == KEY_ESCAPE && mask == MASK_SHIFT) { @@ -2763,32 +2714,67 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) return TRUE; } - // handle escape key - //if (key == KEY_ESCAPE && mask == MASK_NONE) - //{ - - // *TODO: get this to play well with mouselook and hidden - // cursor modes, etc, and re-enable. - //if (gFocusMgr.getMouseCapture()) - //{ - // gFocusMgr.setMouseCapture(NULL); - // return TRUE; - //} - //} - - // let menus handle navigation keys - if (gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE)) + // let menus handle navigation keys for navigation + if ((gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE)) + || (gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE)) + || (gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE))) { return TRUE; } - // let menus handle navigation keys - if (gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE)) + + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); + + // give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus + // as long as focus isn't locked + if (mask & (MASK_CONTROL | MASK_ALT) && !gFocusMgr.focusLocked()) + { + // Check the current floater's menu first, if it has one. + if (gFocusMgr.keyboardFocusHasAccelerators() + && keyboard_focus + && keyboard_focus->handleKey(key,mask,FALSE)) + { + return TRUE; + } + + /* Singu Note: This caused a bug where the menu ate keys before parents of keyboard_focus for some reason, breaking multifloaters usage of ctrl-w to close their selected child floater + if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask)) + || (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))) + { + return TRUE; + } + */ + } + + // give floaters first chance to handle TAB key + // so frontmost floater gets focus + // if nothing has focus, go to first or last UI element as appropriate + if (key == KEY_TAB && (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL)) + { + if (gMenuHolder) gMenuHolder->hideMenus(); + + // if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode + gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0); + + // do CTRL-TAB and CTRL-SHIFT-TAB logic + if (mask & MASK_SHIFT) + { + mRootView->focusPrevRoot(); + } + else + { + mRootView->focusNextRoot(); + } + return TRUE; + } + /* Singu TODO: gEditMenu? + // hidden edit menu for cut/copy/paste + if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask)) { return TRUE; } + */ // Traverses up the hierarchy - LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); if( keyboard_focus ) { // arrow keys move avatar while chatting hack @@ -2799,10 +2785,13 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) if (gChatBar->getCurrentChat().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar")) { - // Singu Note: We do this differently from LL to preserve the Ctrl- behavior in the chatbar + /* Singu Note: We do this differently from LL to preserve the Ctrl- behavior in the chatbar, and we don't need alt because we're not CHUI // let Control-Up and Control-Down through for chat line history, - //if (!(key == KEY_UP && mask == MASK_CONTROL) - // && !(key == KEY_DOWN && mask == MASK_CONTROL)) + if (!(key == KEY_UP && mask == MASK_CONTROL) + && !(key == KEY_DOWN && mask == MASK_CONTROL) + && !(key == KEY_UP && mask == MASK_ALT) + && !(key == KEY_DOWN && mask == MASK_ALT)) + */ { switch(key) { @@ -2824,6 +2813,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) } } } + if (keyboard_focus->handleKey(key, mask, FALSE)) { return TRUE; @@ -2848,43 +2838,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) return TRUE; } - // Topmost view gets a chance before the hierarchy - // *FIX: get rid of this? - //LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); - //if (top_ctrl) - //{ - // if( top_ctrl->handleKey( key, mask, TRUE ) ) - // { - // return TRUE; - // } - //} - - // give floaters first chance to handle TAB key - // so frontmost floater gets focus - if (key == KEY_TAB) - { - // if nothing has focus, go to first or last UI element as appropriate - if (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL) - { - if (gMenuHolder) gMenuHolder->hideMenus(); - - // if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode - gFloaterView->setCycleMode((mask & MASK_CONTROL) != 0); - - // do CTRL-TAB and CTRL-SHIFT-TAB logic - if (mask & MASK_SHIFT) - { - mRootView->focusPrevRoot(); - } - else - { - mRootView->focusNextRoot(); - } - return TRUE; - } - } - - // give menus a chance to handle keys + // give menus a chance to handle unmodified accelerator keys if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask)) ||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))) { @@ -4278,7 +4232,7 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d LLVector3 probe_point_region; // walk forwards to find the point - for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < gAgentCamera.mDrawDistance; mouse_dir_scale += FIRST_PASS_STEP) + for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < gAgentCamera.mDrawDistance * 4; mouse_dir_scale += FIRST_PASS_STEP) { LLVector3d mouse_direction_global_d; mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d0cf9cf21..ae0b13470 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -112,8 +112,11 @@ #include "llfloaterexploreanimations.h" #include "aihttptimeoutpolicy.h" +#include "aixmllindengenepool.h" +#include "aifile.h" #include "llavatarname.h" +#include "../lscript/lscript_byteformat.h" #include "hippogridmanager.h" @@ -129,6 +132,14 @@ #include #include +#if LL_DARWIN +size_t strnlen(const char *s, size_t n) +{ + const char *p = (const char *)memchr(s, 0, n); + return(p ? p-s : n); +} +#endif + using namespace LLAvatarAppearanceDefines; //----------------------------------------------------------------------------- @@ -723,15 +734,11 @@ const LLSD SHClientTagMgr::generateClientTag(const LLVOAvatar* pAvatar) const if(pAvatar->isFullyLoaded() && pTextureEntry->getGlow() > 0.0) { ///llinfos << "Using new client identifier." << llendl; - U8 tag_buffer[UUID_BYTES+1]; - memset(&tag_buffer, 0, UUID_BYTES); - memcpy(&tag_buffer[0], &id.mData, UUID_BYTES); - tag_buffer[UUID_BYTES] = 0; - U32 tag_len = llmin((S32)strlen((const char*)&tag_buffer[0]), UUID_BYTES); - std::string client((char*)&tag_buffer[0], tag_len); + U32 tag_len = strnlen((const char*)&id.mData[0], UUID_BYTES); + std::string client((const char*)&id.mData[0], tag_len); LLStringFn::replace_ascii_controlchars(client, LL_UNKNOWN_CHAR); LLSD info; - info.insert("name", std::string((char*)&tag_buffer[0], tag_len)); + info.insert("name", client); info.insert("color", pTextureEntry->getColor().getValue()); return info; } @@ -6442,8 +6449,6 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) if (attachment->isObjectAttached(viewer_object)) { - cleanupAttachedMesh( viewer_object ); - attachment->removeObject(viewer_object); std::vector >::iterator it = std::find(mAttachedObjectsVector.begin(),mAttachedObjectsVector.end(),std::make_pair(viewer_object,attachment)); if(it != mAttachedObjectsVector.end()) { @@ -6451,6 +6456,8 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) mAttachedObjectsVector.pop_back(); } + cleanupAttachedMesh( viewer_object ); + attachment->removeObject(viewer_object); lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl; return TRUE; } @@ -6600,14 +6607,8 @@ void LLVOAvatar::getOffObject() if (sit_object && !sit_object->permYouOwner() && gSavedSettings.getBOOL("RevokePermsOnStandUp")) { - gMessageSystem->newMessageFast(_PREHASH_RevokePermissions); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_Data); - gMessageSystem->addUUIDFast(_PREHASH_ObjectID, sit_object->getID()); - gMessageSystem->addU32Fast(_PREHASH_ObjectPermissions, 0xFFFFFFFF); - gAgent.sendReliableMessage(); + U32 permissions = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRIGGER_ANIMATION] | LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS]; + gAgent.sendRevokePermissions(sit_object->getID(), permissions); } } } @@ -7676,29 +7677,10 @@ bool LLVOAvatar::visualParamWeightsAreDefault() void dump_visual_param(LLAPRFile& file, LLVisualParam const* viewer_param, F32 value) { - std::string type_string = "unknown"; - if (dynamic_cast(viewer_param)) - type_string = "param_alpha"; - if (dynamic_cast(viewer_param)) - type_string = "param_color"; - if (dynamic_cast(viewer_param)) - type_string = "param_driver"; - if (dynamic_cast(viewer_param)) - type_string = "param_morph"; - if (dynamic_cast(viewer_param)) - type_string = "param_skeleton"; - S32 wtype = -1; - LLViewerVisualParam const* vparam = dynamic_cast(viewer_param); - if (vparam) - { - wtype = vparam->getWearableType(); - } S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight()); apr_file_printf(file.getFileHandle(), " \n", - viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(), - LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str() -// param_location_name(vparam->getParamLocation()).c_str() - ); + viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, viewer_param->getTypeString(), + viewer_param->getDumpWearableTypeName().c_str()); } void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, @@ -8356,127 +8338,83 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara dumpArchetypeXML_cont(fullpath, group_by_wearables); } -// metaversion 1.0 -// =============== -// -// Added as child of : -// -// -// -// Optionally, as child of , the following node may appear: -// -// -// -// Furthermore, metaversion 1.0 and higher allow the occurance of one or more blocks. -// If this is used then it is strongly advised to use one per wearable, so that -// the the node makes sense (it then refers to the wearable of that ). -// -// The reason for this clumsy way to link wearable to extra meta data is to stay -// compatible with the older format (no metaversion). -// -//static -void LLVOAvatar::dumpArchetypeXML_header(LLAPRFile& file, std::string const& archetype_name) -{ - apr_file_t* fp = file.getFileHandle(); - apr_file_printf(fp, "\n"); - apr_file_printf(fp, "\n"); - apr_file_printf(fp, " \n", - LLXMLNode::escapeXML(gHippoGridManager->getConnectedGrid()->getGridNick()).c_str(), - LLDate::now().asString().c_str()); - apr_file_printf(fp, " \n", archetype_name.c_str()); -} - -//static -void LLVOAvatar::dumpArchetypeXML_footer(LLAPRFile& file) -{ - apr_file_t* fp = file.getFileHandle(); - apr_file_printf(fp, " \n"); - apr_file_printf(fp, "\n"); -} - void LLVOAvatar::dumpArchetypeXML_cont(std::string const& fullpath, bool group_by_wearables) { - LLAPRFile outfile; - outfile.open(fullpath, LL_APR_WB ); - apr_file_t* file = outfile.getFileHandle(); - if (!file) + try { - return; + AIFile outfile(fullpath, "wb"); + AIXMLLindenGenepool linden_genepool(outfile); + + if (group_by_wearables) + { + for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) + { + AIArchetype archetype((LLWearableType::EType)type); + + for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + { + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + if( (viewer_param->getWearableType() == type) && + (viewer_param->isTweakable() ) ) + { + archetype.add(AIVisualParamIDValuePair(param)); + } + } + + for (U8 te = 0; te < TEX_NUM_INDICES; te++) + { + if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type) + { + // MULTIPLE_WEARABLES: extend to multiple wearables? + LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); + if( te_image ) + { + archetype.add(AITextureIDUUIDPair(te, te_image->getID())); + } + } + } + + linden_genepool.child(archetype); + } + } + else + { + // Just dump all params sequentially. + AIArchetype archetype; // Legacy: Type is set to WT_NONE and will result in . + + for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) + { + archetype.add(AIVisualParamIDValuePair(param)); + } + + for (U8 te = 0; te < TEX_NUM_INDICES; te++) + { + { + // MULTIPLE_WEARABLES: extend to multiple wearables? + LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); + if( te_image ) + { + archetype.add(AITextureIDUUIDPair(te, te_image->getID())); + } + } + } + + linden_genepool.child(archetype); + } + +#if 0 // Wasn't used anyway. + bool ultra_verbose = false; + if (isSelf() && ultra_verbose) + { + // show the cloned params inside the wearables as well. + gAgentAvatarp->dumpWearableInfo(outfile); + } +#endif } - else + catch (AIAlert::Error const& error) { - llinfos << "xmlfile write handle obtained : " << fullpath << llendl; + AIAlert::add_modal("AIXMLdumpArchetypeXMLError", AIArgs("[FILE]", fullpath), error); } - - LLVOAvatar::dumpArchetypeXML_header(outfile); - - if (group_by_wearables) - { - for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++) - { - const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); - apr_file_printf( file, "\n\t\t\n", wearable_name.c_str() ); - - for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) - { - LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - if( (viewer_param->getWearableType() == type) && - (viewer_param->isTweakable() ) ) - { - dump_visual_param(outfile, viewer_param, viewer_param->getWeight()); - } - } - - for (U8 te = 0; te < TEX_NUM_INDICES; te++) - { - if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type) - { - // MULTIPLE_WEARABLES: extend to multiple wearables? - LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); - if( te_image ) - { - std::string uuid_str; - te_image->getID().toString( uuid_str ); - apr_file_printf( file, "\t\t\n", te, uuid_str.c_str()); - } - } - } - } - } - else - { - // Just dump all params sequentially. - for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) - { - LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - dump_visual_param(outfile, viewer_param, viewer_param->getWeight()); - } - - for (U8 te = 0; te < TEX_NUM_INDICES; te++) - { - { - // MULTIPLE_WEARABLES: extend to multiple wearables? - LLViewerTexture* te_image = getImage((ETextureIndex)te, 0); - if( te_image ) - { - std::string uuid_str; - te_image->getID().toString( uuid_str ); - apr_file_printf( file, "\t\t\n", te, uuid_str.c_str()); - } - } - } - - } - - LLVOAvatar::dumpArchetypeXML_footer(outfile); - - bool ultra_verbose = false; - if (isSelf() && ultra_verbose) - { - // show the cloned params inside the wearables as well. - gAgentAvatarp->dumpWearableInfo(outfile); - } - // File will close when handle goes out of scope } void LLVOAvatar::setVisibilityRank(U32 rank) diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 6fdd2c277..ab2833220 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -325,29 +325,55 @@ BOOL LLVOAvatarSelf::buildMenus() //------------------------------------------------------------------------- if(gNoRender) return TRUE; - gAttachBodyPartPieMenus[0] = NULL; - gAttachBodyPartPieMenus[1] = new LLPieMenu(LLTrans::getString("BodyPartsRightArm") + " >"); - gAttachBodyPartPieMenus[2] = new LLPieMenu(LLTrans::getString("BodyPartsHead") + " >"); - gAttachBodyPartPieMenus[3] = new LLPieMenu(LLTrans::getString("BodyPartsLeftArm") + " >"); - gAttachBodyPartPieMenus[4] = NULL; - gAttachBodyPartPieMenus[5] = new LLPieMenu(LLTrans::getString("BodyPartsLeftLeg") + " >"); - gAttachBodyPartPieMenus[6] = new LLPieMenu(LLTrans::getString("BodyPartsTorso") + " >"); - gAttachBodyPartPieMenus[7] = new LLPieMenu(LLTrans::getString("BodyPartsRightLeg") + " >"); + buildContextMenus(); - gDetachBodyPartPieMenus[0] = NULL; - gDetachBodyPartPieMenus[1] = new LLPieMenu(LLTrans::getString("BodyPartsRightArm") + " >"); - gDetachBodyPartPieMenus[2] = new LLPieMenu(LLTrans::getString("BodyPartsHead") + " >"); - gDetachBodyPartPieMenus[3] = new LLPieMenu(LLTrans::getString("BodyPartsLeftArm") + " >"); - gDetachBodyPartPieMenus[4] = NULL; - gDetachBodyPartPieMenus[5] = new LLPieMenu(LLTrans::getString("BodyPartsLeftLeg") + " >"); - gDetachBodyPartPieMenus[6] = new LLPieMenu(LLTrans::getString("BodyPartsTorso") + " >"); - gDetachBodyPartPieMenus[7] = new LLPieMenu(LLTrans::getString("BodyPartsRightLeg") + " >"); + init_meshes_and_morphs_menu(); + + return TRUE; +} + +// Convenience function to create context or pie menu with label +static LLContextMenu* make_part_menu(const std::string& label, bool context) +{ + return context ? new LLContextMenu(label) : new LLPieMenu(label + " >"); +} + +void LLVOAvatarSelf::buildContextMenus() +{ + gAttachBodyPartPieMenus[0] = gDetachBodyPartPieMenus[0] = NULL; + + bool context(gSavedSettings.getBOOL("LiruUseContextMenus")); + std::string label = LLTrans::getString("BodyPartsRightArm"); + gAttachBodyPartPieMenus[1] = make_part_menu(label, context); + gDetachBodyPartPieMenus[1] = make_part_menu(label, context); + + label = LLTrans::getString("BodyPartsHead"); + gAttachBodyPartPieMenus[2] = make_part_menu(label, context); + gDetachBodyPartPieMenus[2] = make_part_menu(label, context); + + label = LLTrans::getString("BodyPartsLeftArm"); + gAttachBodyPartPieMenus[3] = make_part_menu(label, context); + gDetachBodyPartPieMenus[3] = make_part_menu(label, context); + + gAttachBodyPartPieMenus[4] = gDetachBodyPartPieMenus[4] = NULL; + + label = LLTrans::getString("BodyPartsLeftLeg"); + gAttachBodyPartPieMenus[5] = make_part_menu(label, context); + gDetachBodyPartPieMenus[5] = make_part_menu(label, context); + + label = LLTrans::getString("BodyPartsTorso"); + gAttachBodyPartPieMenus[6] = make_part_menu(label, context); + gDetachBodyPartPieMenus[6] = make_part_menu(label, context); + + label = LLTrans::getString("BodyPartsRightLeg"); + gAttachBodyPartPieMenus[7] = make_part_menu(label, context); + gDetachBodyPartPieMenus[7] = make_part_menu(label, context); for (S32 i = 0; i < 8; i++) { if (gAttachBodyPartPieMenus[i]) { - gAttachPieMenu->appendPieMenu( gAttachBodyPartPieMenus[i] ); + gAttachPieMenu->appendContextSubMenu( gAttachBodyPartPieMenus[i] ); } else { @@ -379,7 +405,7 @@ BOOL LLVOAvatarSelf::buildMenus() } } - if (!attachment_found) + if (!context && !attachment_found) { gAttachPieMenu->addSeparator(); } @@ -387,7 +413,7 @@ BOOL LLVOAvatarSelf::buildMenus() if (gDetachBodyPartPieMenus[i]) { - gDetachPieMenu->appendPieMenu( gDetachBodyPartPieMenus[i] ); + gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] ); } else { @@ -407,7 +433,7 @@ BOOL LLVOAvatarSelf::buildMenus() } } - if (!attachment_found) + if (!context && !attachment_found) { gDetachPieMenu->addSeparator(); } @@ -466,7 +492,7 @@ BOOL LLVOAvatarSelf::buildMenus() &handle_detach_from_avatar, object_attached, &detach_label, attachment)); } - if (pass == 0) + if (!context && pass == 0) { // put separator between non-hud and hud attachments gAttachSubMenu->addSeparator(); @@ -503,14 +529,17 @@ BOOL LLVOAvatarSelf::buildMenus() for (std::multimap::iterator attach_it = attachment_pie_menu_map.begin(); attach_it != attachment_pie_menu_map.end(); ++attach_it) { - S32 requested_pie_slice = attach_it->first; - S32 attach_index = attach_it->second; - while (cur_pie_slice < requested_pie_slice) + if (!context) // Singu Note: Separators are only needed to keep slices of pies from moving { - gAttachBodyPartPieMenus[group]->addSeparator(); - gDetachBodyPartPieMenus[group]->addSeparator(); - cur_pie_slice++; + S32 requested_pie_slice = attach_it->first; + while (cur_pie_slice < requested_pie_slice) + { + gAttachBodyPartPieMenus[group]->addSeparator(); + gDetachBodyPartPieMenus[group]->addSeparator(); + cur_pie_slice++; + } } + S32 attach_index = attach_it->second; LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL); if (attachment) @@ -527,14 +556,10 @@ BOOL LLVOAvatarSelf::buildMenus() gDetachBodyPartPieMenus[group]->addChild(new LLMenuItemCallGL(attachment->getName(), &handle_detach_from_avatar, object_attached, attachment)); - cur_pie_slice++; + if (!context) cur_pie_slice++; } } } - - init_meshes_and_morphs_menu(); - - return TRUE; } void LLVOAvatarSelf::cleanup() diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 99e45bcff..2c9d69b8b 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -63,6 +63,7 @@ public: virtual ~LLVOAvatarSelf(); virtual void markDead(); virtual void initInstance(); // Called after construction to initialize the class. + void buildContextMenus(); void cleanup(); protected: /*virtual*/ BOOL loadAvatar(); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 84ac30bf8..af93ec553 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -84,6 +84,7 @@ extern LLColor4U MAX_WATER_COLOR; // Aurora Sim //const U32 LLWorld::mWidth = 256; U32 LLWorld::mWidth = 256; +U32 LLWorld::mLength = 256; // Aurora Sim // meters/point, therefore mWidth * mScale = meters per edge @@ -152,9 +153,10 @@ void LLWorld::destroyClass() } } -void LLWorld::setRegionWidth(const U32 width) +void LLWorld::setRegionSize(const U32& width, const U32& length) { mWidth = width ? width : 256; // Width of 0 is really 256 + mLength = length ? length : 256; // Length of 0 is really 256 mWidthInMeters = mWidth * mScale; } @@ -247,7 +249,7 @@ LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host) adj_x = region_x + width * gDirAxes[dir][0]; adj_y = region_y + width * gDirAxes[dir][1]; - if (mWidth == 256) + if (mWidth == 256 && mLength == 256) { to_region_handle(adj_x, adj_y, &adj_handle); neighborp = getRegionFromHandle(adj_handle); @@ -1361,7 +1363,9 @@ void process_enable_simulator(LLMessageSystem *msg, void **user_data) // Aurora Sim U32 region_size_x = 256; msg->getU32Fast(_PREHASH_SimulatorInfo, _PREHASH_RegionSizeX, region_size_x); - LLWorld::getInstance()->setRegionWidth(region_size_x); + U32 region_size_y = 256; + msg->getU32Fast(_PREHASH_SimulatorInfo, _PREHASH_RegionSizeY, region_size_y); + LLWorld::getInstance()->setRegionSize(region_size_x, region_size_y); // Aurora Sim LLWorld::getInstance()->addRegion(handle, sim); diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 291159540..b363d0d67 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -115,7 +115,7 @@ public: LLVector3 resolveLandNormalGlobal(const LLVector3d &position); // absolute frame // update region size - void setRegionWidth(const U32 width = 0); + void setRegionSize(const U32& width = 0, const U32& length = 0); U32 getRegionWidthInPoints() const { return mWidth; } F32 getRegionScale() const { return mScale; } @@ -188,6 +188,7 @@ private: // Aurora Sim //static const U32 mWidth; static U32 mWidth; + static U32 mLength; // Aurora Sim // meters/point, therefore mWidth * mScale = meters per edge diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 42180df08..e6aec53bb 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -109,6 +109,8 @@ #include "llwaterparammanager.h" #include "llspatialpartition.h" #include "llmutelist.h" +#include "llfloatertools.h" +#include "llpanelface.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvhandler.h" @@ -319,6 +321,7 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE; BOOL LLPipeline::sRenderSoundBeacons = FALSE; BOOL LLPipeline::sRenderBeacons = FALSE; BOOL LLPipeline::sRenderHighlight = TRUE; +LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP; BOOL LLPipeline::sForceOldBakedUpload = FALSE; S32 LLPipeline::sUseOcclusion = 0; BOOL LLPipeline::sDelayVBUpdate = FALSE; @@ -3839,6 +3842,8 @@ void LLPipeline::postSort(LLCamera& camera) { mSelectedFaces.clear(); + LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit()); + // Draw face highlights for selected faces. if (LLSelectMgr::getInstance()->getTEMode()) { @@ -3938,13 +3943,14 @@ void LLPipeline::renderHighlights() gGL.diffuseColor4f(1,1,1,0.5f); } - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep) + { + mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP)) { // Make sure the selection image gets downloaded and decoded - if (!mFaceSelectImagep) - { - mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); - } mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); U32 count = mSelectedFaces.size(); @@ -3982,6 +3988,67 @@ void LLPipeline::renderHighlights() { gHighlightProgram.unbind(); } + + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)) + { + color.setVec(1.0f, 0.5f, 0.5f, 0.5f); + if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightNormalProgram.bind(); + gGL.diffuseColor4f(1,1,1,0.5f); + } + + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) + { + LLFace *facep = mSelectedFaces[i]; + if (!facep || facep->getDrawable()->isDead()) + { + llerrs << "Bad face on selection" << llendl; + return; + } + + facep->renderSelected(mFaceSelectImagep, color); + } + + if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightNormalProgram.unbind(); + } + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)) + { + color.setVec(0.0f, 0.3f, 1.0f, 0.8f); + if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightSpecularProgram.bind(); + gGL.diffuseColor4f(1,1,1,0.5f); + } + + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) + { + LLFace *facep = mSelectedFaces[i]; + if (!facep || facep->getDrawable()->isDead()) + { + llerrs << "Bad face on selection" << llendl; + return; + } + + facep->renderSelected(mFaceSelectImagep, color); + } + + if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightSpecularProgram.unbind(); + } + } } //debug use @@ -6399,6 +6466,12 @@ BOOL LLPipeline::getRenderHighlights(void*) return sRenderHighlight; } +// static +void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel) +{ + sRenderHighlightTextureChannel = channel; +} + LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection, S32* face_hit) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 75f03f52c..453512d80 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -413,6 +413,7 @@ public: static void setRenderHighlights(BOOL val); static void toggleRenderHighlights(void* data); static BOOL getRenderHighlights(void* data); + static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay static void updateRenderDeferred(); static void refreshCachedSettings(); @@ -837,6 +838,10 @@ public: static BOOL sRenderBeacons; static BOOL sRenderHighlight; + // Determines which set of UVs to use in highlight display + // + static LLRender::eTexIndex sRenderHighlightTextureChannel; + //debug use static U32 sCurRenderPoolType ; }; diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 58d60ee33..6e492ae15 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -138,8 +138,8 @@ TOOLMEDIAOPEN CURSOR "toolmediaopen.cur" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,0,0 - PRODUCTVERSION 1,5,0,0 + FILEVERSION 1,8,4,5433 + PRODUCTVERSION 1,8,4,5433 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -156,12 +156,12 @@ BEGIN BEGIN VALUE "CompanyName", "Siana Gearz" VALUE "FileDescription", "Singularity Viewer" - VALUE "FileVersion", "1.5.0.0" + VALUE "FileVersion", "1.8.4.5433" VALUE "InternalName", "Second Life" VALUE "LegalCopyright", "Copyright © 2001-2010, Linden Research, Inc., Copyright 2010 Siana Gearz" - VALUE "OriginalFilename", "singularity.exe" + VALUE "OriginalFilename", "SingularityViewer.exe" VALUE "ProductName", "Singularity Viewer" - VALUE "ProductVersion", "1.5.0.0" + VALUE "ProductVersion", "1.8.4.5433" END END BLOCK "VarFileInfo" diff --git a/indra/newview/res/viewerRes_bc.rc b/indra/newview/res/viewerRes_bc.rc index 6649c21c9..7827f7ded 100644 --- a/indra/newview/res/viewerRes_bc.rc +++ b/indra/newview/res/viewerRes_bc.rc @@ -138,8 +138,8 @@ TOOLMEDIAOPEN CURSOR "toolmediaopen.cur" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,0,0 - PRODUCTVERSION 1,5,0,0 + FILEVERSION 1,8,4,5433 + PRODUCTVERSION 1,8,4,5433 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -156,12 +156,12 @@ BEGIN BEGIN VALUE "CompanyName", "Siana Gearz" VALUE "FileDescription", "Singularity Viewer" - VALUE "FileVersion", "1.5.0.0" + VALUE "FileVersion", "1.8.4.5433" VALUE "InternalName", "Second Life" VALUE "LegalCopyright", "Copyright © 2001-2010, Linden Research, Inc., Copyright 2010 Siana Gearz" - VALUE "OriginalFilename", "singularity.exe" + VALUE "OriginalFilename", "SingularityViewer.exe" VALUE "ProductName", "Singularity Viewer" - VALUE "ProductVersion", "1.5.0.0" + VALUE "ProductVersion", "1.8.4.5433" END END BLOCK "VarFileInfo" diff --git a/indra/newview/skins/default/textures/Cam_Preset_Back_Off.png b/indra/newview/skins/default/textures/Cam_Preset_Back_Off.png new file mode 100644 index 000000000..00158a7bc Binary files /dev/null and b/indra/newview/skins/default/textures/Cam_Preset_Back_Off.png differ diff --git a/indra/newview/skins/default/textures/Cam_Preset_Back_On.png b/indra/newview/skins/default/textures/Cam_Preset_Back_On.png new file mode 100644 index 000000000..3748f5e19 Binary files /dev/null and b/indra/newview/skins/default/textures/Cam_Preset_Back_On.png differ diff --git a/indra/newview/skins/default/textures/Cam_Preset_Front_Off.png b/indra/newview/skins/default/textures/Cam_Preset_Front_Off.png new file mode 100644 index 000000000..c49b8f9a2 Binary files /dev/null and b/indra/newview/skins/default/textures/Cam_Preset_Front_Off.png differ diff --git a/indra/newview/skins/default/textures/Cam_Preset_Front_On.png b/indra/newview/skins/default/textures/Cam_Preset_Front_On.png new file mode 100644 index 000000000..bc8c4db04 Binary files /dev/null and b/indra/newview/skins/default/textures/Cam_Preset_Front_On.png differ diff --git a/indra/newview/skins/default/textures/Cam_Preset_Side_Off.png b/indra/newview/skins/default/textures/Cam_Preset_Side_Off.png new file mode 100644 index 000000000..b919a0a15 Binary files /dev/null and b/indra/newview/skins/default/textures/Cam_Preset_Side_Off.png differ diff --git a/indra/newview/skins/default/textures/Cam_Preset_Side_On.png b/indra/newview/skins/default/textures/Cam_Preset_Side_On.png new file mode 100644 index 000000000..de9da359a Binary files /dev/null and b/indra/newview/skins/default/textures/Cam_Preset_Side_On.png differ diff --git a/indra/newview/skins/default/textures/Edit_Flip_X.png b/indra/newview/skins/default/textures/Edit_Flip_X.png new file mode 100644 index 000000000..5106b4359 Binary files /dev/null and b/indra/newview/skins/default/textures/Edit_Flip_X.png differ diff --git a/indra/newview/skins/default/textures/green_checkmark.png b/indra/newview/skins/default/textures/green_checkmark.png new file mode 100644 index 000000000..d2a5b348d Binary files /dev/null and b/indra/newview/skins/default/textures/green_checkmark.png differ diff --git a/indra/newview/skins/default/textures/materials_ui_x_24.png b/indra/newview/skins/default/textures/materials_ui_x_24.png new file mode 100644 index 000000000..6d8855491 Binary files /dev/null and b/indra/newview/skins/default/textures/materials_ui_x_24.png differ diff --git a/indra/newview/skins/default/textures/red_x.png b/indra/newview/skins/default/textures/red_x.png new file mode 100644 index 000000000..a61202f09 Binary files /dev/null and b/indra/newview/skins/default/textures/red_x.png differ diff --git a/indra/newview/skins/default/xui/de/menu_pie_attachment.xml b/indra/newview/skins/default/xui/de/menu_pie_attachment.xml index da6e10ad0..dd6092c32 100644 --- a/indra/newview/skins/default/xui/de/menu_pie_attachment.xml +++ b/indra/newview/skins/default/xui/de/menu_pie_attachment.xml @@ -5,8 +5,8 @@ - - + + diff --git a/indra/newview/skins/default/xui/de/menu_pie_avatar.xml b/indra/newview/skins/default/xui/de/menu_pie_avatar.xml index 53988dd8d..6288151a6 100644 --- a/indra/newview/skins/default/xui/de/menu_pie_avatar.xml +++ b/indra/newview/skins/default/xui/de/menu_pie_avatar.xml @@ -6,11 +6,11 @@ - + - + diff --git a/indra/newview/skins/default/xui/de/menu_pie_object.xml b/indra/newview/skins/default/xui/de/menu_pie_object.xml index 254eaeb92..bf03eeb99 100644 --- a/indra/newview/skins/default/xui/de/menu_pie_object.xml +++ b/indra/newview/skins/default/xui/de/menu_pie_object.xml @@ -6,16 +6,16 @@ - + - - + + - + - + @@ -29,11 +29,11 @@ - + - + diff --git a/indra/newview/skins/default/xui/de/menu_pie_self.xml b/indra/newview/skins/default/xui/de/menu_pie_self.xml index 7184ae7cd..5f0ad5214 100644 --- a/indra/newview/skins/default/xui/de/menu_pie_self.xml +++ b/indra/newview/skins/default/xui/de/menu_pie_self.xml @@ -2,15 +2,15 @@ - - + + - + @@ -21,13 +21,13 @@ - + - + - + diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index d8587485f..6d6f2bba0 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -69,25 +69,6 @@ - Export Failure: could not open file "[FILE]" for writing. - - Import Warning: could not apply textures: [FILE] was exported on grid "[GRIDNAME]" while the currentgrid is "[CURGRID]". - - Import Failure: could not read or parse wearable import file "[FILE]". - - Import Failure: the file "[FILE]" is not a linden_genepool XML file. - - Import Failure: the file "[FILE]" contains linden_genepool XML data with the wrong [TAG]. Version "[VERSIONMAJOR].0" or less is required. - - Import Failure: the file "[FILE]" contains invalid data. - - Import was successful but note that the wearable was exported on grid [EXPORTGRID] (and the current grid is [CURRENTGRID]). Texture UUIDs have NOT been applied! - - Import was successful but note that the wearable was exported on grid [EXPORTGRID] (and the current grid is [CURRENTGRID]). Texture UUIDs have been applied but might not exist here! - - Import Warning: the file "[FILE]" does not contain a wearable of type [TYPE]. -It contains an archetype of type [ARCHETYPENAME]. Please select the correct type before importing. - Der Besitzer der Parzelle möchte Ihren Viewer anweisen die folgende [TYPE] URL zu laden:[URL]Sie können die korrespondierende Domäne oder In-Welt Objekt-Skript-Server erlauben oder ablehnen."Erlauben" und "Verweigern" gelten nur für die aktuelle Sitzung, während "Immer sperren" bzw. "Immer erlauben" dann immer gelten.
- - - - - + + + + + + + + +