76 (ChatCmd: '/finish'; ProcedureCallChatCmd: 'finish'), |
77 (ChatCmd: '/finish'; ProcedureCallChatCmd: 'finish'), |
77 (ChatCmd: '/history'; ProcedureCallChatCmd: 'history'), |
78 (ChatCmd: '/history'; ProcedureCallChatCmd: 'history'), |
78 (ChatCmd: '/fullscreen'; ProcedureCallChatCmd: 'fullscr') |
79 (ChatCmd: '/fullscreen'; ProcedureCallChatCmd: 'fullscr') |
79 ); |
80 ); |
80 |
81 |
|
82 |
|
83 const Padding = 2; |
|
84 ClHeight = 2 * Padding + 16; // font height |
|
85 |
|
86 procedure RenderChatLineTex(var cl: TChatLine; var str: shortstring); |
|
87 var strSurface, |
|
88 resSurface: PSDL_Surface; |
|
89 dstrect : TSDL_Rect; // destination rectangle for blitting |
|
90 font : THWFont; |
|
91 const |
|
92 shadowcolor: TSDL_Color = (r:$00; g:$00; b:$00; a:$80); |
|
93 shadowint = $80 shl AShift; |
|
94 begin |
|
95 |
|
96 font:= CheckCJKFont(ansistring(str), fnt16); |
|
97 |
|
98 // get render size of text |
|
99 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @cl.Width, nil); |
|
100 |
|
101 // calculate and save size |
|
102 cl.Width := cl.Width + 2 * Padding; |
|
103 |
|
104 // create surface to draw on |
|
105 resSurface:= SDL_CreateRGBSurface( |
|
106 0, toPowerOf2(cl.Width), toPowerOf2(ClHeight), |
|
107 32, RMask, GMask, BMask, AMask); |
|
108 |
|
109 // define area we want to draw in |
|
110 dstrect.x:= 0; |
|
111 dstrect.y:= 0; |
|
112 dstrect.w:= cl.Width; |
|
113 dstrect.h:= ClHeight; |
|
114 |
|
115 // draw background |
|
116 SDL_FillRect(resSurface, @dstrect, shadowint); |
|
117 |
|
118 // prepare destination rectangle for text shadow |
|
119 // start position in texture should have padding; add 1 px as shadow offset |
|
120 dstrect.x:= Padding + 1; |
|
121 dstrect.y:= Padding + 1; |
|
122 // doesn't matter if .w and .h still include padding, SDL_UpperBlit will clip |
|
123 |
|
124 |
|
125 // create and blit text shadow |
|
126 strSurface:= TTF_RenderUTF8_Solid(Fontz[font].Handle, Str2PChar(str), shadowcolor); |
|
127 SDL_UpperBlit(strSurface, nil, resSurface, @dstrect); |
|
128 SDL_FreeSurface(strSurface); |
|
129 |
|
130 // non-shadow text starts at padding |
|
131 dstrect.x:= Padding; |
|
132 dstrect.y:= Padding; |
|
133 |
|
134 // create and blit text |
|
135 strSurface:= TTF_RenderUTF8_Solid(Fontz[font].Handle, Str2PChar(str), cl.color); |
|
136 SDL_UpperBlit(strSurface, nil, resSurface, @dstrect); |
|
137 SDL_FreeSurface(strSurface); |
|
138 |
|
139 cl.Tex:= Surface2Tex(resSurface, false); |
|
140 |
|
141 SDL_FreeSurface(resSurface) |
|
142 end; |
|
143 |
|
144 const ClDisplayDuration = 12500; |
|
145 |
81 procedure SetLine(var cl: TChatLine; str: shortstring; isInput: boolean); |
146 procedure SetLine(var cl: TChatLine; str: shortstring; isInput: boolean); |
82 var strSurface, resSurface: PSDL_Surface; |
147 var color : TSDL_Color; |
83 w, h: LongInt; |
|
84 color: TSDL_Color; |
|
85 font: THWFont; |
|
86 begin |
148 begin |
87 if cl.Tex <> nil then |
149 if cl.Tex <> nil then |
88 FreeTexture(cl.Tex); |
150 FreeTexture(cl.Tex); |
89 |
151 |
90 cl.s:= str; |
|
91 |
|
92 if isInput then |
152 if isInput then |
93 begin |
153 begin |
|
154 cl.s:= str; |
94 color:= colors[#6]; |
155 color:= colors[#6]; |
95 str:= UserNick + '> ' + str + '_' |
156 str:= UserNick + '> ' + str + '_' |
96 end |
157 end |
97 else |
158 else |
98 begin |
159 begin |
99 color:= colors[str[1]]; |
160 color:= colors[str[1]]; |
100 delete(str, 1, 1) |
161 delete(str, 1, 1); |
101 end; |
162 cl.s:= str; |
102 |
163 end; |
103 font:= CheckCJKFont(ansistring(str), fnt16); |
164 |
104 w:= 0; h:= 0; // avoid compiler hints |
165 cl.color:= color; |
105 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), @w, @h); |
166 |
106 |
167 // set texture, note: variables cl.s and str will be different here if isInput |
107 resSurface:= SDL_CreateRGBSurface(0, toPowerOf2(w), toPowerOf2(h), 32, RMask, GMask, BMask, AMask); |
168 RenderChatLineTex(cl, str); |
108 |
169 |
109 strSurface:= TTF_RenderUTF8_Solid(Fontz[font].Handle, Str2PChar(str), color); |
170 cl.Time:= RealTicks + ClDisplayDuration; |
110 cl.Width:= w + 4; |
|
111 SDL_UpperBlit(strSurface, nil, resSurface, nil); |
|
112 SDL_FreeSurface(strSurface); |
|
113 |
|
114 cl.Time:= RealTicks + 12500; |
|
115 cl.Tex:= Surface2Tex(resSurface, false); |
|
116 |
|
117 SDL_FreeSurface(resSurface) |
|
118 end; |
171 end; |
119 |
172 |
120 // For uStore texture recreation |
173 // For uStore texture recreation |
121 procedure ReloadLines; |
174 procedure ReloadLines; |
122 var i, t: LongWord; |
175 var i, t: LongWord; |
150 |
203 |
151 inc(visibleCount) |
204 inc(visibleCount) |
152 end; |
205 end; |
153 |
206 |
154 procedure DrawChat; |
207 procedure DrawChat; |
155 var i, t, cnt: Longword; |
208 var i, t, left, top, cnt: Longword; |
156 r: TSDL_Rect; |
|
157 begin |
209 begin |
158 ChatReady:= true; // maybe move to somewhere else? |
210 ChatReady:= true; // maybe move to somewhere else? |
159 if MissedCount <> 0 then // there are chat strings we missed, so print them now |
211 if MissedCount <> 0 then // there are chat strings we missed, so print them now |
160 begin |
212 begin |
161 for i:= 0 to MissedCount - 1 do |
213 for i:= 0 to MissedCount - 1 do |
162 AddChatString(MStrs[i]); |
214 AddChatString(MStrs[i]); |
163 MissedCount:= 0; |
215 MissedCount:= 0; |
164 end; |
216 end; |
165 cnt:= 0; |
|
166 t:= 0; |
|
167 i:= lastStr; |
217 i:= lastStr; |
168 |
218 |
169 r.x:= 6 - cScreenWidth div 2; |
219 left:= 4 - cScreenWidth div 2; |
170 r.y:= (visibleCount - t) * 16 + 10; |
220 top := 10; |
171 r.h:= 16; |
|
172 |
221 |
173 if (GameState = gsChat) and (InputStr.Tex <> nil) then |
222 if (GameState = gsChat) and (InputStr.Tex <> nil) then |
174 begin |
223 begin |
175 r.w:= InputStr.Width; |
224 // draw under all other lines |
176 DrawFillRect(r); |
225 DrawTexture(left, top + visibleCount * ClHeight, InputStr.Tex); |
177 Tint($00, $00, $00, $80); |
226 end; |
178 DrawTexture(9 - cScreenWidth div 2, visibleCount * 16 + 11, InputStr.Tex); |
227 |
179 untint; |
228 |
180 DrawTexture(8 - cScreenWidth div 2, visibleCount * 16 + 10, InputStr.Tex); |
229 cnt:= 0; // count of lines displayed |
181 end; |
230 t := 1; // # of current line processed |
182 |
231 |
183 dec(r.y, 16); |
232 // draw lines in reverse order |
184 |
|
185 while (((t < 7) and (Strs[i].Time > RealTicks)) or ((t < MaxStrIndex) and showAll)) |
233 while (((t < 7) and (Strs[i].Time > RealTicks)) or ((t < MaxStrIndex) and showAll)) |
186 and (Strs[i].Tex <> nil) do |
234 and (Strs[i].Tex <> nil) do |
187 begin |
235 begin |
188 r.w:= Strs[i].Width; |
236 // draw lines 4px away from left screen border and 2px away from top |
189 DrawFillRect(r); |
237 DrawTexture(left, top + (visibleCount - t) * ClHeight, Strs[i].Tex); |
190 Tint($00, $00, $00, $80); |
|
191 DrawTexture(9 - cScreenWidth div 2, (visibleCount - t) * 16 - 5, Strs[i].Tex); |
|
192 untint; |
|
193 DrawTexture(8 - cScreenWidth div 2, (visibleCount - t) * 16 - 6, Strs[i].Tex); |
|
194 dec(r.y, 16); |
|
195 |
238 |
196 if i = 0 then |
239 if i = 0 then |
197 i:= MaxStrIndex |
240 i:= MaxStrIndex |
198 else |
241 else |
199 dec(i); |
242 dec(i); |