hedgewars/uChat.pas
changeset 10303 f726e36c3e24
parent 10127 7f29a65aa1e4
child 10304 7e40820b7ed6
equal deleted inserted replaced
10302:ea0b0e2efd95 10303:f726e36c3e24
    39 type TChatLine = record
    39 type TChatLine = record
    40     Tex: PTexture;
    40     Tex: PTexture;
    41     Time: Longword;
    41     Time: Longword;
    42     Width: LongInt;
    42     Width: LongInt;
    43     s: shortstring;
    43     s: shortstring;
       
    44     Color: TSDL_Color;
    44     end;
    45     end;
    45     TChatCmd = (ccQuit, ccPause, ccFinish, ccShowHistory, ccFullScreen);
    46     TChatCmd = (ccQuit, ccPause, ccFinish, ccShowHistory, ccFullScreen);
    46 
    47 
    47 var Strs: array[0 .. MaxStrIndex] of TChatLine;
    48 var Strs: array[0 .. MaxStrIndex] of TChatLine;
    48     MStrs: array[0 .. MaxStrIndex] of shortstring;
    49     MStrs: array[0 .. MaxStrIndex] of shortstring;
    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);