1 /***************************************************************************
2 textscroller.cpp - "Scrolling text lines" widget
3 -------------------
4 begin : Sat Apr 14 2007
5 copyright : (C) 2003 by Gabor Torok
6 email : cctorok@yahoo.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17 #include "common/constants.h"
18 #include "textscroller.h"
19 #include "scourge.h"
20 #include "sdlhandler.h"
21 #include "render/map.h"
22 #include "shapepalette.h"
23
24 // ###### MS Visual C++ specific ######
25 #if defined(_MSC_VER) && defined(_DEBUG)
26 # define new DEBUG_NEW
27 # undef THIS_FILE
28 static char THIS_FILE[] = __FILE__;
29 #endif
30
31 using namespace std;
32
33 #define LINE_HEIGHT 15
34 #define LINES_SHOWN 7
35 #define SCROLL_SPEED 100
36 #define OFFSET_DELTA 1
37 #define MAX_QUEUE_SIZE 200
38 #define SCROLL_WIDTH 500
39
TextScroller(Scourge * scourge)40 TextScroller::TextScroller( Scourge *scourge ) {
41 this->scourge = scourge;
42 this->xp = 300;
43 this->yp = 0;
44 startOffset = lineOffset = 0;
45 offset = 0;
46 lastCheck = SDL_GetTicks();
47 inside = false;
48 visible = false;
49 scrollTexture = 0;
50 }
51
~TextScroller()52 TextScroller::~TextScroller() {
53 for ( size_t i = 0; i < color.size(); ++i ) {
54 delete color[i];
55 }
56 }
57
addDescription(char const * description,float r,float g,float b,int logLevel)58 void TextScroller::addDescription( char const* description, float r, float g, float b, int logLevel ) {
59 if ( scourge->getUserConfiguration()->getLogLevel() < logLevel ) return;
60
61 string s = description;
62 color.insert( color.begin(), new Color( r, g, b, 1 ) );
63 text.insert( text.begin(), s );
64 if ( text.size() == MAX_QUEUE_SIZE ) {
65 text.erase( text.end() - 1 );
66 Color *c = color[ color.size() - 1 ];
67 delete( c );
68 color.erase( color.end() - 1 );
69 }
70 }
71
writeLogMessage(char const * message,int messageType,int logLevel)72 void TextScroller::writeLogMessage( char const* message, int messageType, int logLevel ) {
73
74 if ( messageType == Constants::MSGTYPE_NORMAL ) {
75 addDescription( message, 1, 1, 0, logLevel );
76 } else if ( messageType == Constants::MSGTYPE_MISSION ) {
77 addDescription( message, 1, 1, 1, logLevel );
78 } else if ( messageType == Constants::MSGTYPE_PLAYERDAMAGE ) {
79 addDescription( message, 1, 0, 0, logLevel );
80 } else if ( messageType == Constants::MSGTYPE_NPCDAMAGE ) {
81 addDescription( message, 0, 1, 0, logLevel );
82 } else if ( messageType == Constants::MSGTYPE_PLAYERMAGIC ) {
83 addDescription( message, 1, 0, 1, logLevel );
84 } else if ( messageType == Constants::MSGTYPE_NPCMAGIC ) {
85 addDescription( message, 0.7f, 0, 1, logLevel );
86 } else if ( messageType == Constants::MSGTYPE_PLAYERITEM ) {
87 addDescription( message, 0, 0, 1, logLevel );
88 } else if ( messageType == Constants::MSGTYPE_NPCITEM ) {
89 addDescription( message, 0, 0.5f, 1, logLevel );
90 } else if ( messageType == Constants::MSGTYPE_PLAYERBATTLE ) {
91 addDescription( message, 1, 0.8f, 0.8f, logLevel );
92 } else if ( messageType == Constants::MSGTYPE_NPCBATTLE ) {
93 addDescription( message, 1, 0.5f, 0.5f, logLevel );
94 } else if ( messageType == Constants::MSGTYPE_PLAYERDEATH ) {
95 addDescription( message, 0.7f, 0.7f, 0, logLevel );
96 } else if ( messageType == Constants::MSGTYPE_NPCDEATH ) {
97 addDescription( message, 0, 0.7f, 0, logLevel );
98 } else if ( messageType == Constants::MSGTYPE_FAILURE ) {
99 addDescription( message, 0.7f, 0.7f, 0.7f, logLevel );
100 } else if ( messageType == Constants::MSGTYPE_STATS ) {
101 addDescription( message, 1, 0.5f, 0, logLevel );
102 } else if ( messageType == Constants::MSGTYPE_SYSTEM ) {
103 addDescription( message, 0, 0.8f, 0.8f, logLevel );
104 } else if ( messageType == Constants::MSGTYPE_SKILL ) {
105 addDescription( message, 0, 1, 1, logLevel );
106 }
107 }
108
draw()109 void TextScroller::draw() {
110
111 if ( !visible ) {
112 lineOffset = 0;
113 }
114
115 if ( scourge->getParty()->isRealTimeMode() && !visible ) {
116 Uint32 now = SDL_GetTicks();
117 if ( now - lastCheck > SCROLL_SPEED ) {
118 lastCheck = now;
119 offset += OFFSET_DELTA;
120 if ( offset >= LINE_HEIGHT ) {
121 offset = 0;
122 text.insert( text.begin(), "" );
123 color.insert( color.begin(), new Color( 0, 0, 0, 0 ) );
124 for ( unsigned int i = LINES_SHOWN; i < text.size(); i++ ) {
125 if ( text[i] == "" ) {
126 text.erase( text.begin() + i );
127 Color *c = color[ i ];
128 delete( c );
129 color.erase( color.begin() + i );
130 i--;
131 }
132 }
133 }
134 }
135 }
136
137 int height = LINES_SHOWN * LINE_HEIGHT;
138
139 glPushMatrix();
140 glLoadIdentity();
141 int ytop = ( scourge->inTurnBasedCombat() ? yp + 50 : yp );
142 glTranslatef( xp, ytop, 0 );
143 glDisable( GL_DEPTH_TEST );
144
145 if ( visible ) {
146 int margin = 10;
147 glEnable( GL_BLEND );
148 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
149 glDisable( GL_TEXTURE_2D );
150 // glColor4f( 1, 1, 1, 0.25f );
151 glColor4f( 0, 0, 0, 0.5f );
152 glBegin( GL_TRIANGLE_STRIP );
153 glVertex2d( -margin, 0 );
154 glVertex2d( SCROLL_WIDTH + margin, 0 );
155 glVertex2d( -margin, height + margin );
156 glVertex2d( SCROLL_WIDTH + margin, height + margin );
157 glEnd();
158 glColor4f( 0.5f, 0.5f, 0.5f, 1 );
159 glBegin( GL_LINE_LOOP );
160 glVertex2d( -margin, height + margin );
161 glVertex2d( -margin, 0 );
162 glVertex2d( SCROLL_WIDTH + margin, 0 );
163 glVertex2d( SCROLL_WIDTH + margin, height + margin );
164 glEnd();
165
166 glBegin( GL_LINE_LOOP );
167 glVertex2d( SCROLL_WIDTH + margin - 10, height );
168 glVertex2d( SCROLL_WIDTH + margin - 10, 10 );
169 glVertex2d( SCROLL_WIDTH + margin - 7, 10 );
170 glVertex2d( SCROLL_WIDTH + margin - 7, height );
171 glEnd();
172 int ypos = static_cast<int>( ( lineOffset * ( height - 10 ) ) / static_cast<float>( text.size() - 1 ) );
173 glBegin( GL_TRIANGLE_STRIP );
174 glVertex2d( SCROLL_WIDTH + margin - 10, height - ( ypos + 10 ) );
175 glVertex2d( SCROLL_WIDTH + margin - 7, height - ( ypos + 10 ) );
176 glVertex2d( SCROLL_WIDTH + margin - 10, height - ypos );
177 glVertex2d( SCROLL_WIDTH + margin - 7, height - ypos );
178 glEnd();
179
180 glEnable( GL_TEXTURE_2D );
181 glDisable( GL_BLEND );
182 }
183
184 glScissor( xp, scourge->getScreenHeight() - ( ytop + height ), SCROLL_WIDTH, height );
185 glEnable( GL_SCISSOR_TEST );
186
187 int currentOffset = ( visible ? 0 : offset );
188 int x = 0;
189 int y = height - currentOffset;
190 // cerr << "text.size=" << text.size() << endl;
191 for ( unsigned int i = lineOffset; static_cast<int>( i ) < lineOffset + LINES_SHOWN && i < text.size(); i++ ) {
192 if ( text[ i ] != "" ) {
193 Color *c = color[ i ];
194 float a;
195 if ( visible ) a = 1;
196 else a = c->a * ( ( LINES_SHOWN - ( ( i - lineOffset ) + ( currentOffset / static_cast<float>( LINE_HEIGHT ) ) ) ) / static_cast<float>( LINES_SHOWN ) );
197 glColor4f( c->r, c->g, c->b, a );
198 scourge->getSDLHandler()->texPrint( x, y, text[ i ].c_str() );
199 }
200 y -= LINE_HEIGHT;
201 }
202 glDisable( GL_SCISSOR_TEST );
203 glEnable( GL_DEPTH_TEST );
204 glPopMatrix();
205 glColor4f( 1, 1, 1, 1 );
206 }
207
scrollUp()208 void TextScroller::scrollUp() {
209 }
210
scrollDown()211 void TextScroller::scrollDown() {
212 }
213
handleEvent(SDL_Event * event)214 bool TextScroller::handleEvent( SDL_Event *event ) {
215 int mx = scourge->getSDLHandler()->mouseX;
216 int my = scourge->getSDLHandler()->mouseY;
217 int ytop = ( scourge->inTurnBasedCombat() ? yp + 50 : yp );
218 bool before = visible;
219 inside = ( mx >= xp && mx < xp + SCROLL_WIDTH &&
220 my >= ytop && my < ytop + LINES_SHOWN * LINE_HEIGHT &&
221 !( scourge->getSession()->getMap()->isMouseRotating() ||
222 scourge->getSession()->getMap()->isMouseZooming() ||
223 scourge->getSession()->getMap()->isMapMoving() ) );
224 if ( inside && !before && my >= ytop && my <= ytop + 15 ) {
225 visible = true;
226 startOffset = lineOffset = 0;
227 for ( unsigned int i = 0; i < text.size(); i++ ) {
228 if ( text[i] != "" ) {
229 startOffset = lineOffset = i;
230 break;
231 }
232 }
233 }
234
235 if ( !inside && before ) visible = false;
236
237 if ( event->type == SDL_MOUSEBUTTONDOWN ) {
238 if ( inside && visible ) {
239 if ( event->button.button == SDL_BUTTON_WHEELUP ) {
240 lineOffset++;
241 if ( lineOffset + LINES_SHOWN >= static_cast<int>( text.size() ) ) {
242 lineOffset = text.size() - LINES_SHOWN + 1;
243 }
244 } else if ( event->button.button == SDL_BUTTON_WHEELDOWN ) {
245 lineOffset--;
246 if ( lineOffset < startOffset ) lineOffset = startOffset;
247 }
248 }
249 }
250 return visible;
251 }
252
253