hedgewars/uChat.pas
changeset 2948 3f21a9dc93d0
parent 2716 b9ca1bfca24f
child 3038 4e48c276a468
equal deleted inserted replaced
2947:803b277e4894 2948:3f21a9dc93d0
    36 uses uMisc, uStore, uConsts, SDLh, uConsole, uKeys, uTeams;
    36 uses uMisc, uStore, uConsts, SDLh, uConsole, uKeys, uTeams;
    37 
    37 
    38 const MaxStrIndex = 27;
    38 const MaxStrIndex = 27;
    39 
    39 
    40 type TChatLine = record
    40 type TChatLine = record
    41 		Tex: PTexture;
    41         Tex: PTexture;
    42 		Time: Longword;
    42         Time: Longword;
    43 		Width: LongInt;
    43         Width: LongInt;
    44 		s: shortstring;
    44         s: shortstring;
    45 		end;
    45         end;
    46 
    46 
    47 var Strs: array[0 .. MaxStrIndex] of TChatLine;
    47 var Strs: array[0 .. MaxStrIndex] of TChatLine;
    48     lastStr: LongWord;
    48     lastStr: LongWord;
    49     visibleCount: LongWord;
    49     visibleCount: LongWord;
    50     InputStr: TChatLine;
    50     InputStr: TChatLine;
    51     InputStrL: array[0..260] of char; // for full str + 4-byte utf-8 char
    51     InputStrL: array[0..260] of char; // for full str + 4-byte utf-8 char
    52 
    52 
    53 const colors: array[#1..#4] of TSDL_Color = (
    53 const colors: array[#1..#4] of TSDL_Color = (
    54 	(r:$FF; g:$FF; b:$FF; unused:$FF), // chat message [White]
    54     (r:$FF; g:$FF; b:$FF; unused:$FF), // chat message [White]
    55 	(r:$FF; g:$00; b:$FF; unused:$FF), // action message [Purple]
    55     (r:$FF; g:$00; b:$FF; unused:$FF), // action message [Purple]
    56 	(r:$90; g:$FF; b:$90; unused:$FF), // join/leave message [Lime]
    56     (r:$90; g:$FF; b:$90; unused:$FF), // join/leave message [Lime]
    57 	(r:$FF; g:$FF; b:$A0; unused:$FF)  // team message [Light Yellow]
    57     (r:$FF; g:$FF; b:$A0; unused:$FF)  // team message [Light Yellow]
    58 	);
    58     );
    59 
    59 
    60 procedure SetLine(var cl: TChatLine; str: shortstring; isInput: boolean);
    60 procedure SetLine(var cl: TChatLine; str: shortstring; isInput: boolean);
    61 var strSurface, resSurface: PSDL_Surface;
    61 var strSurface, resSurface: PSDL_Surface;
    62 	w, h: LongInt;
    62     w, h: LongInt;
    63 	color: TSDL_Color;
    63     color: TSDL_Color;
    64     font: THWFont;
    64     font: THWFont;
    65 begin
    65 begin
    66 if cl.Tex <> nil then
    66 if cl.Tex <> nil then
    67 	FreeTexture(cl.Tex);
    67     FreeTexture(cl.Tex);
    68 
    68 
    69 
    69 
    70 cl.s:= str;
    70 cl.s:= str;
    71 
    71 
    72 if isInput then
    72 if isInput then
    73 begin
    73 begin
    74 	// [Light Blue]
    74     // [Light Blue]
    75 	color.r:= $00;
    75     color.r:= $00;
    76 	color.g:= $FF;
    76     color.g:= $FF;
    77 	color.b:= $FF;
    77     color.b:= $FF;
    78 	color.unused:= $FF;
    78     color.unused:= $FF;
    79 	str:= UserNick + '> ' + str + '_'
    79     str:= UserNick + '> ' + str + '_'
    80 end
    80 end
    81 else
    81 else
    82 begin
    82 begin
    83 	color:= colors[str[1]];
    83     color:= colors[str[1]];
    84 	delete(str, 1, 1)
    84     delete(str, 1, 1)
    85 end;
    85 end;
    86 
    86 
    87 font:= CheckCJKFont(str, fnt16);
    87 font:= CheckCJKFont(str, fnt16);
    88 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), w, h);
    88 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(str), w, h);
    89 
    89 
   109 inc(visibleCount)
   109 inc(visibleCount)
   110 end;
   110 end;
   111 
   111 
   112 procedure DrawChat;
   112 procedure DrawChat;
   113 var i, t, cnt: Longword;
   113 var i, t, cnt: Longword;
   114 	r: TSDL_Rect;
   114     r: TSDL_Rect;
   115 begin
   115 begin
   116 cnt:= 0;
   116 cnt:= 0;
   117 t:= 0;
   117 t:= 0;
   118 i:= lastStr;
   118 i:= lastStr;
   119 
   119 
   120 r.x:= 6 - cScreenWidth div 2;
   120 r.x:= 6 - cScreenWidth div 2;
   121 r.y:= (visibleCount - t) * 16 + 10;
   121 r.y:= (visibleCount - t) * 16 + 10;
   122 r.h:= 16;
   122 r.h:= 16;
   123 
   123 
   124 if (GameState = gsChat)
   124 if (GameState = gsChat)
   125 	and (InputStr.Tex <> nil) then
   125     and (InputStr.Tex <> nil) then
   126 	begin
   126     begin
   127 	r.w:= InputStr.Width;
   127     r.w:= InputStr.Width;
   128 	DrawFillRect(r);
   128     DrawFillRect(r);
   129 	DrawTexture(8 - cScreenWidth div 2, visibleCount * 16 + 10, InputStr.Tex);
   129     DrawTexture(8 - cScreenWidth div 2, visibleCount * 16 + 10, InputStr.Tex);
   130 	end;
   130     end;
   131 
   131 
   132 dec(r.y, 16);
   132 dec(r.y, 16);
   133 
   133 
   134 while
   134 while
   135 	(
   135     (
   136 			((t < 7) and (Strs[i].Time > RealTicks))
   136             ((t < 7) and (Strs[i].Time > RealTicks))
   137 		or
   137         or
   138 			((t < MaxStrIndex) and showAll)
   138             ((t < MaxStrIndex) and showAll)
   139 	)
   139     )
   140 	and
   140     and
   141 		(Strs[i].Tex <> nil) do
   141         (Strs[i].Tex <> nil) do
   142 	begin
   142     begin
   143 	r.w:= Strs[i].Width;
   143     r.w:= Strs[i].Width;
   144 	DrawFillRect(r);
   144     DrawFillRect(r);
   145 	DrawTexture(8 - cScreenWidth div 2, (visibleCount - t) * 16 - 6, Strs[i].Tex);
   145     DrawTexture(8 - cScreenWidth div 2, (visibleCount - t) * 16 - 6, Strs[i].Tex);
   146 	dec(r.y, 16);
   146     dec(r.y, 16);
   147 
   147 
   148 	if i = 0 then i:= MaxStrIndex else dec(i);
   148     if i = 0 then i:= MaxStrIndex else dec(i);
   149 	inc(cnt);
   149     inc(cnt);
   150 	inc(t)
   150     inc(t)
   151 	end;
   151     end;
   152 
   152 
   153 visibleCount:= cnt;
   153 visibleCount:= cnt;
   154 end;
   154 end;
   155 
   155 
   156 procedure AcceptChatString(s: shortstring);
   156 procedure AcceptChatString(s: shortstring);
   214     begin
   214     begin
   215     ParseCommand(s, true);
   215     ParseCommand(s, true);
   216     exit
   216     exit
   217     end;
   217     end;
   218 if (s[1] = '/') and (copy(s, 1, 4) <> '/me ') then
   218 if (s[1] = '/') and (copy(s, 1, 4) <> '/me ') then
   219 	begin
   219     begin
   220 	if CurrentTeam^.ExtDriven then exit;
   220     if CurrentTeam^.ExtDriven then exit;
   221 
   221 
   222 	for i:= Low(TWave) to High(TWave) do
   222     for i:= Low(TWave) to High(TWave) do
   223 		if (s = Wavez[i].cmd) then
   223         if (s = Wavez[i].cmd) then
   224 			begin
   224             begin
   225 			ParseCommand('/taunt ' + char(i), true);
   225             ParseCommand('/taunt ' + char(i), true);
   226 			exit
   226             exit
   227 			end;
   227             end;
   228 	if (s = '/newgrave') then
   228     if (s = '/newgrave') then
   229         begin
   229         begin
   230 	    ParseCommand('/newgrave', true);
   230         ParseCommand('/newgrave', true);
   231         exit
   231         exit
   232         end;
   232         end;
   233     end
   233     end
   234 	else
   234     else
   235 		ParseCommand('/say ' + s, true);
   235         ParseCommand('/say ' + s, true);
   236 end;
   236 end;
   237 
   237 
   238 procedure KeyPressChat(Key: Longword);
   238 procedure KeyPressChat(Key: Longword);
   239 const firstByteMark: array[1..4] of byte = (0, $C0, $E0, $F0);
   239 const firstByteMark: array[1..4] of byte = (0, $C0, $E0, $F0);
   240 var i, btw: integer;
   240 var i, btw: integer;
   241     utf8: shortstring;
   241     utf8: shortstring;
   242 begin
   242 begin
   243 
   243 
   244 if Key <> 0 then
   244 if Key <> 0 then
   245 	case Key of
   245     case Key of
   246 		{Backspace}
   246         {Backspace}
   247 		8, 127: if Length(InputStr.s) > 0 then
   247         8, 127: if Length(InputStr.s) > 0 then
   248 				begin
   248                 begin
   249 				InputStr.s[0]:= InputStrL[byte(InputStr.s[0])];
   249                 InputStr.s[0]:= InputStrL[byte(InputStr.s[0])];
   250 				SetLine(InputStr, InputStr.s, true)
   250                 SetLine(InputStr, InputStr.s, true)
   251 				end;
   251                 end;
   252 		{Esc}
   252         {Esc}
   253 		27: SetLine(InputStr, '', true);
   253         27: SetLine(InputStr, '', true);
   254 		{Return}
   254         {Return}
   255 		3, 13, 271: begin
   255         3, 13, 271: begin
   256 			if Length(InputStr.s) > 0 then
   256             if Length(InputStr.s) > 0 then
   257 				begin
   257                 begin
   258 				AcceptChatString(InputStr.s);
   258                 AcceptChatString(InputStr.s);
   259 				SetLine(InputStr, '', false)
   259                 SetLine(InputStr, '', false)
   260 				end;
   260                 end;
   261 			FreezeEnterKey;
   261             FreezeEnterKey;
   262 			GameState:= gsGame
   262             GameState:= gsGame
   263 			end;
   263             end;
   264 	else
   264     else
   265 	if (Key < $80) then btw:= 1
   265     if (Key < $80) then btw:= 1
   266 	else if (Key < $800) then btw:= 2
   266     else if (Key < $800) then btw:= 2
   267 	else if (Key < $10000) then btw:= 3
   267     else if (Key < $10000) then btw:= 3
   268 	else btw:= 4;
   268     else btw:= 4;
   269 
   269 
   270 	utf8:= '';
   270     utf8:= '';
   271 
   271 
   272 	for i:= btw downto 2 do
   272     for i:= btw downto 2 do
   273 		begin
   273         begin
   274 		utf8:= char((Key or $80) and $BF) + utf8;
   274         utf8:= char((Key or $80) and $BF) + utf8;
   275 		Key:= Key shr 6
   275         Key:= Key shr 6
   276 		end;
   276         end;
   277 
   277 
   278 	utf8:= char(Key or firstByteMark[btw]) + utf8;
   278     utf8:= char(Key or firstByteMark[btw]) + utf8;
   279 
   279 
   280 	if byte(InputStr.s[0]) + btw > 240 then exit;
   280     if byte(InputStr.s[0]) + btw > 240 then exit;
   281 
   281 
   282 	InputStrL[byte(InputStr.s[0]) + btw]:= InputStr.s[0];
   282     InputStrL[byte(InputStr.s[0]) + btw]:= InputStr.s[0];
   283 	SetLine(InputStr, InputStr.s + utf8, true)
   283     SetLine(InputStr, InputStr.s + utf8, true)
   284 	end
   284     end
   285 end;
   285 end;
   286 
   286 
   287 procedure init_uChat;
   287 procedure init_uChat;
   288 begin
   288 begin
   289     lastStr:= 0;
   289     lastStr:= 0;