00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llconsole.h"
00035
00036
00037 #include "llmath.h"
00038 #include "llviewercontrol.h"
00039 #include "llcriticaldamp.h"
00040 #include "llfontgl.h"
00041 #include "llgl.h"
00042 #include "llui.h"
00043 #include "llviewerimage.h"
00044 #include "llviewerimagelist.h"
00045 #include "llviewerwindow.h"
00046 #include "llfontgl.h"
00047 #include "llmath.h"
00048
00049 #include "llstartup.h"
00050
00051
00052 extern void AddNewDebugConsoleToLCD(const LLWString &newLine);
00053
00054 LLConsole* gConsole = NULL;
00055
00056 const F32 FADE_DURATION = 2.f;
00057 const S32 MIN_CONSOLE_WIDTH = 200;
00058
00059 LLConsole::LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect,
00060 S32 font_size_index, F32 persist_time )
00061 :
00062 LLFixedBuffer(max_lines),
00063 LLView(name, rect, FALSE),
00064 mLastBoxHeight(0),
00065 mLastBoxWidth(0)
00066 {
00067 mLinePersistTime = persist_time;
00068 mFadeTime = persist_time - FADE_DURATION;
00069
00070 setFontSize( font_size_index );
00071 setMaxLines(gSavedSettings.getS32("ConsoleMaxLines"));
00072 }
00073
00074 LLConsole::~LLConsole()
00075 {
00076 mColors.clear();
00077 }
00078
00079 void LLConsole::setLinePersistTime(F32 seconds)
00080 {
00081 mLinePersistTime = seconds;
00082 mFadeTime = mLinePersistTime - FADE_DURATION;
00083 }
00084
00085 void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent)
00086 {
00087 S32 new_width = llmax(50, llmin(getRect().getWidth(), gViewerWindow->getWindowWidth()));
00088 S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(getRect().getHeight(), gViewerWindow->getWindowHeight()));
00089
00090 LLView::reshape(new_width, new_height, called_from_parent);
00091 }
00092
00093 void LLConsole::setFontSize(S32 size_index)
00094 {
00095 if (-1 == size_index)
00096 {
00097 mFont = LLFontGL::sMonospace;
00098 }
00099 else if (0 == size_index)
00100 {
00101 mFont = LLFontGL::sSansSerif;
00102 }
00103 else if (1 == size_index)
00104 {
00105 mFont = LLFontGL::sSansSerifBig;
00106 }
00107 else
00108 {
00109 mFont = LLFontGL::sSansSerifHuge;
00110 }
00111 }
00112
00113 void LLConsole::draw()
00114 {
00115 LLGLSUIDefault gls_ui;
00116
00117 addQueuedLines();
00118
00119
00120 F32 cur_time = mTimer.getElapsedTimeF32();
00121
00122 if( LLStartUp::getStartupState() != STATE_STARTED )
00123 {
00124 S32 count = mLines.size();
00125 S32 i = 0;
00126 while( count-- )
00127 {
00128 mAddTimes[i] = cur_time;
00129 i = (i+1) % mMaxLines;
00130 }
00131 }
00132
00133 F32 skip_time = cur_time - mLinePersistTime;
00134 F32 fade_time = cur_time - mFadeTime;
00135
00136
00137 F32 x_pos = 0.f;
00138 F32 y_pos = 0.f;
00139
00140 S32 line_count = mLines.size();
00141
00142
00143 for (S32 line_num = 0; line_num < line_count; line_num++)
00144 {
00145 if((mLinePersistTime > 0.f) && (mAddTimes[0] - skip_time)/(mLinePersistTime - mFadeTime) <= 0.f)
00146 {
00147 mLines.pop_front();
00148 mAddTimes.pop_front();
00149 mLineLengths.pop_front();
00150 mColors.pop_front();
00151 }
00152 }
00153
00154 line_count = mLines.size();
00155
00156 S32 i;
00157 if (line_count == 0)
00158 {
00159 mLastBoxHeight = 0;
00160 mLastBoxWidth = 0;
00161 return;
00162 }
00163 else
00164 {
00165 LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga");
00166
00167 F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
00168 LLColor4 color = gColors.getColor("ConsoleBackground");
00169 color.mV[VALPHA] *= console_opacity;
00170
00171 S32 max_width = 0;
00172 for (i = 0; i < line_count; i++)
00173 {
00174 max_width = llmax(max_width, mFont->getWidth(mLines[i].c_str()) + 30);
00175 }
00176 max_width = llmin(max_width, gViewerWindow->getWindowWidth());
00177
00178 F32 u = 1.f;
00179 S32 target_height = llfloor(line_count * mFont->getLineHeight() + 15);
00180 S32 target_width = max_width;
00181 mLastBoxHeight = llmax(target_height, (S32)lerp((F32)mLastBoxHeight, (F32)target_height, u));
00182 mLastBoxWidth = llmax(MIN_CONSOLE_WIDTH, llmax(target_width, (S32)lerp((F32)mLastBoxWidth, (F32)target_width, u)));
00183 imagep->drawSolid(-15, -10, mLastBoxWidth + 15, mLastBoxHeight, color);
00184 }
00185
00186 y_pos += (line_count-1) * mFont->getLineHeight();
00187
00188
00189 for (i = 0; i < line_count; i++)
00190 {
00191 F32 alpha;
00192
00193 if ((mLinePersistTime > 0.f) && (mAddTimes[i] < fade_time))
00194 {
00195 alpha = (mAddTimes[i] - skip_time)/(mLinePersistTime - mFadeTime);
00196 }
00197 else
00198 {
00199 alpha = 1.0f;
00200 }
00201
00202 if( alpha > 0.f )
00203 {
00204
00205 mFont->render(mLines[i], 0, x_pos, y_pos,
00206 LLColor4(
00207 mColors[i].mV[VRED],
00208 mColors[i].mV[VGREEN],
00209 mColors[i].mV[VBLUE],
00210 mColors[i].mV[VALPHA]*alpha),
00211 LLFontGL::LEFT,
00212 LLFontGL::BASELINE,
00213 LLFontGL::DROP_SHADOW,
00214 S32_MAX,
00215 mLastBoxWidth
00216 );
00217 }
00218
00219 y_pos -= mFont->getLineHeight();
00220 }
00221 }
00222
00223 void LLConsole::addLine(const LLString& utf8line)
00224 {
00225 LLWString wline = utf8str_to_wstring(utf8line);
00226 addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
00227 }
00228
00229 void LLConsole::addLine(const LLWString& wline)
00230 {
00231 addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
00232 }
00233
00234 void LLConsole::addLine(const LLString& utf8line, F32 size, const LLColor4 &color)
00235 {
00236 LLWString wline = utf8str_to_wstring(utf8line);
00237 addLine(wline, size, color);
00238 }
00239
00240 void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
00241 {
00242 while (mLineQueue.size() >= mMaxLines)
00243 {
00244 mLineQueue.pop_front();
00245 }
00246 mLineQueue.push_back(LineInfo(wline, size, color, mTimer.getElapsedTimeF32()));
00247 #if LL_WINDOWS && LL_LCD_COMPILE
00248
00249 AddNewDebugConsoleToLCD(wline);
00250 #endif
00251 }
00252
00253 void LLConsole::addQueuedLines()
00254 {
00255 for (line_queue_t::iterator iter = mLineQueue.begin();
00256 iter != mLineQueue.end(); ++iter)
00257 {
00258 LineInfo& line_info = *iter;
00259 LLWString wline = line_info.wline;
00260
00261 LLColor4 color = line_info.color;
00262 if (!wline.empty() && mFont != NULL)
00263 {
00264
00265 S32 line_start_offset = 0;
00266 while( line_start_offset < (S32)wline.length() )
00267 {
00268
00269 LLWString::size_type line_end = wline.find_first_of(llwchar('\n'), line_start_offset);
00270 if (LLWString::npos == line_end)
00271 {
00272
00273 line_end = wline.size();
00274 }
00275
00276 U32 drawable = mFont->maxDrawableChars(wline.c_str()+line_start_offset, (F32)getRect().getWidth(), line_end-line_start_offset, TRUE);
00277 if (drawable != 0)
00278 {
00279 LLFixedBuffer::addLine(wline.substr(line_start_offset, drawable));
00280 mAddTimes[mAddTimes.size()-1] = line_info.add_time;
00281
00282
00283 line_start_offset += drawable;
00284 }
00285 else
00286 {
00287
00288 LLFixedBuffer::addLine(" ");
00289 line_start_offset++;
00290 }
00291 mColors.push_back(color);
00292
00293 if (line_start_offset == line_end)
00294 {
00295 line_start_offset++;
00296 }
00297 }
00298 }
00299 }
00300 mLineQueue.clear();
00301 }
00302
00303 void LLConsole::removeExtraLines()
00304 {
00305 while((S32)mColors.size() > llmax(0, (S32)(mMaxLines - 1)))
00306 {
00307 mColors.pop_front();
00308 }
00309 LLFixedBuffer::removeExtraLines();
00310 }