hedgewars/uIO.pas
changeset 2574 2f3e5c57359c
parent 2407 9f413bd5150e
child 2578 ec8e69b23097
equal deleted inserted replaced
2573:a7db29d7e2d0 2574:2f3e5c57359c
    43 const isPonged: boolean = false;
    43 const isPonged: boolean = false;
    44 
    44 
    45 type PCmd = ^TCmd;
    45 type PCmd = ^TCmd;
    46      TCmd = packed record
    46      TCmd = packed record
    47             Next: PCmd;
    47             Next: PCmd;
    48             Time: LongWord;
    48             loTime: Word;
    49             case byte of
    49             case byte of
    50             1: (len: byte;
    50             1: (len: byte;
    51                 cmd: Char;
    51                 cmd: Char;
    52                 X, Y: SmallInt);
    52                 X, Y: SmallInt);
    53             2: (str: shortstring);
    53             2: (str: shortstring);
    61 	lastcmd: PCmd = nil;
    61 	lastcmd: PCmd = nil;
    62 
    62 
    63 	SendEmptyPacketTicks: LongWord = 0;
    63 	SendEmptyPacketTicks: LongWord = 0;
    64 
    64 
    65 
    65 
    66 function AddCmd(Time: Longword; str: shortstring): PCmd;
    66 function AddCmd(Time: Word; str: shortstring): PCmd;
    67 var Result: PCmd;
    67 var Result: PCmd;
    68 begin
    68 begin
    69 new(Result);
    69 new(Result);
    70 FillChar(Result^, sizeof(TCmd), 0);
    70 FillChar(Result^, sizeof(TCmd), 0);
    71 Result^.Time:= Time;
    71 Result^.loTime:= Time;
    72 Result^.str:= str;
    72 Result^.str:= str;
    73 if Result^.cmd <> 'F' then dec(Result^.len, 2); // cut timestamp
    73 if Result^.cmd <> 'F' then dec(Result^.len, 2); // cut timestamp
    74 if headcmd = nil then
    74 if headcmd = nil then
    75    begin
    75    begin
    76    headcmd:= Result;
    76    headcmd:= Result;
   119 var loTicks: Word;
   119 var loTicks: Word;
   120 begin
   120 begin
   121 case s[1] of
   121 case s[1] of
   122      '!': begin {$IFDEF DEBUGFILE}AddFileLog('Ping? Pong!');{$ENDIF}isPonged:= true; end;
   122      '!': begin {$IFDEF DEBUGFILE}AddFileLog('Ping? Pong!');{$ENDIF}isPonged:= true; end;
   123      '?': SendIPC('!');
   123      '?': SendIPC('!');
   124      '#': inc(hiTicks);
       
   125      'e': ParseCommand(copy(s, 2, Length(s) - 1), true);
   124      'e': ParseCommand(copy(s, 2, Length(s) - 1), true);
   126      'E': OutError(copy(s, 2, Length(s) - 1), true);
   125      'E': OutError(copy(s, 2, Length(s) - 1), true);
   127      'W': OutError(copy(s, 2, Length(s) - 1), false);
   126      'W': OutError(copy(s, 2, Length(s) - 1), false);
   128      'M': CheckLandDigest(s);
   127      'M': CheckLandDigest(s);
   129      'T': case s[2] of
   128      'T': case s[2] of
   132                'N': GameType:= gmtNet;
   131                'N': GameType:= gmtNet;
   133                'S': GameType:= gmtSave;
   132                'S': GameType:= gmtSave;
   134                else OutError(errmsgIncorrectUse + ' IPC "T" :' + s[2], true) end;
   133                else OutError(errmsgIncorrectUse + ' IPC "T" :' + s[2], true) end;
   135      else
   134      else
   136      loTicks:= SDLNet_Read16(@s[byte(s[0]) - 1]);
   135      loTicks:= SDLNet_Read16(@s[byte(s[0]) - 1]);
   137      AddCmd(hiTicks shl 16 + loTicks, s);
   136      AddCmd(loTicks, s);
   138      {$IFDEF DEBUGFILE}AddFileLog('IPC in: '+s[1]+' ticks '+inttostr(lastcmd^.Time));{$ENDIF}
   137      {$IFDEF DEBUGFILE}AddFileLog('IPC in: '+s[1]+' ticks '+inttostr(lastcmd^.loTime));{$ENDIF}
   139      end
   138      end
   140 end;
   139 end;
   141 
   140 
   142 procedure IPCCheckSock;
   141 procedure IPCCheckSock;
   143 const ss: string = '';
   142 const ss: string = '';
   263 	s: shortstring;
   262 	s: shortstring;
   264 begin
   263 begin
   265 tmpflag:= true;
   264 tmpflag:= true;
   266 
   265 
   267 while (headcmd <> nil)
   266 while (headcmd <> nil)
   268 	and tmpflag
   267 	and (tmpflag or (headcmd^.cmd = '#')) // '#' is the only cmd which can be sent within same tick after 'N'
   269 	and ((GameTicks = headcmd^.Time)
   268 	and ((GameTicks = hiTicks shl 16 + headcmd^.loTime)
   270 		or (headcmd^.cmd = 's')
   269 		or (headcmd^.cmd = 's') // for these commands time isn't specified
   271 		or (headcmd^.cmd = 'b')
   270 		or (headcmd^.cmd = '#')
       
   271  		or (headcmd^.cmd = 'b')
   272 		or (headcmd^.cmd = 'F')) do
   272 		or (headcmd^.cmd = 'F')) do
   273 	begin
   273 	begin
   274 	case headcmd^.cmd of
   274 	case headcmd^.cmd of
   275 		'+': ; // do nothing - it is just empty packet
   275 		'+': ; // do nothing - it is just an empty packet
       
   276 		'#': inc(hiTicks);
   276 		'L': ParseCommand('+left', true);
   277 		'L': ParseCommand('+left', true);
   277 		'l': ParseCommand('-left', true);
   278 		'l': ParseCommand('-left', true);
   278 		'R': ParseCommand('+right', true);
   279 		'R': ParseCommand('+right', true);
   279 		'r': ParseCommand('-right', true);
   280 		'r': ParseCommand('-right', true);
   280 		'U': ParseCommand('+up', true);
   281 		'U': ParseCommand('+up', true);
   300 			WriteLnToConsole(s)
   301 			WriteLnToConsole(s)
   301 			end;
   302 			end;
   302 		'F': TeamGone(copy(headcmd^.str, 2, Pred(headcmd^.len)));
   303 		'F': TeamGone(copy(headcmd^.str, 2, Pred(headcmd^.len)));
   303 		'N': begin
   304 		'N': begin
   304 			tmpflag:= false;
   305 			tmpflag:= false;
   305 			{$IFDEF DEBUGFILE}AddFileLog('got cmd "N": time '+inttostr(headcmd^.Time)){$ENDIF}
   306 			{$IFDEF DEBUGFILE}AddFileLog('got cmd "N": time '+inttostr(hiTicks shl 16 + headcmd^.loTime)){$ENDIF}
   306 			end;
   307 			end;
   307 		'p': begin
   308 		'p': begin
   308 			TargetPoint.X:= SDLNet_Read16(@(headcmd^.X));
   309 			TargetPoint.X:= SDLNet_Read16(@(headcmd^.X));
   309 			TargetPoint.Y:= SDLNet_Read16(@(headcmd^.Y));
   310 			TargetPoint.Y:= SDLNet_Read16(@(headcmd^.Y));
   310 			ParseCommand('put', true)
   311 			ParseCommand('put', true)
   311 			end;
   312 			end;
   312 		'P': begin
   313 		'P': begin
   313 			// these are equations solved for CursorPoint
   314 			// these are equations solved for CursorPoint
   314 			// SDLNet_Read16(@(headcmd^.X)):= CursorPoint.X - WorldDx;
   315 			// SDLNet_Read16(@(headcmd^.X)) == CursorPoint.X - WorldDx;
   315 			// SDLNet_Read16(@(headcmd^.Y)):= cScreenHeight - CursorPoint.Y - WorldDy;
   316 			// SDLNet_Read16(@(headcmd^.Y)) == cScreenHeight - CursorPoint.Y - WorldDy;
   316 			CursorPoint.X:= SDLNet_Read16(@(headcmd^.X)) + WorldDx;
   317 			CursorPoint.X:= SDLNet_Read16(@(headcmd^.X)) + WorldDx;
   317 			CursorPoint.Y:= cScreenHeight - SDLNet_Read16(@(headcmd^.Y)) - WorldDy;
   318 			CursorPoint.Y:= cScreenHeight - SDLNet_Read16(@(headcmd^.Y)) - WorldDy;
   318 			end;
   319 			end;
   319 		'w': ParseCommand('setweap ' + headcmd^.str[2], true);
   320 		'w': ParseCommand('setweap ' + headcmd^.str[2], true);
   320 		't': ParseCommand('taunt ' + headcmd^.str[2], true);
   321 		't': ParseCommand('taunt ' + headcmd^.str[2], true);
   326 			OutError('Unexpected protocol command: ' + headcmd^.cmd, True)
   327 			OutError('Unexpected protocol command: ' + headcmd^.cmd, True)
   327 		end;
   328 		end;
   328 	RemoveCmd
   329 	RemoveCmd
   329 	end;
   330 	end;
   330 
   331 
   331 if (headcmd <> nil) and tmpflag then
   332 if (headcmd <> nil) and tmpflag and (not CurrentTeam^.hasGone) then
   332 	TryDo(GameTicks < headcmd^.Time,
   333 	TryDo(GameTicks < hiTicks shl 16 + headcmd^.loTime,
   333 			'oops, queue error. in buffer: ' + headcmd^.cmd +
   334 			'oops, queue error. in buffer: ' + headcmd^.cmd +
   334 			' (' + inttostr(GameTicks) + ' > ' +
   335 			' (' + inttostr(GameTicks) + ' > ' +
   335 			inttostr(headcmd^.Time) + ')',
   336 			inttostr(hiTicks shl 16 + headcmd^.loTime) + ')',
   336 			true);
   337 			true);
   337 
   338 
   338 isInLag:= (headcmd = nil) and tmpflag and (not CurrentTeam^.hasGone);
   339 isInLag:= (headcmd = nil) and tmpflag and (not CurrentTeam^.hasGone);
   339 
   340 
   340 if isInLag then fastUntilLag:= false
   341 if isInLag then fastUntilLag:= false