hedgewars/uIO.pas
changeset 4436 94c948a92759
parent 4414 cb90b7f82cd5
child 4467 adedeec8f18f
equal deleted inserted replaced
4366:d19adc635c99 4436:94c948a92759
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uIO;
    21 unit uIO;
    22 interface
    22 interface
    23 uses SDLh;
    23 uses SDLh, uTypes;
    24 
    24 
    25 var ipcPort: Word = 0;
    25 var ipcPort: Word = 0;
    26     hiTicks: Word;
    26     hiTicks: Word;
    27 
    27 
    28 procedure initModule;
    28 procedure initModule;
    33 procedure SendIPCRaw(p: pointer; len: Longword);
    33 procedure SendIPCRaw(p: pointer; len: Longword);
    34 procedure SendIPCAndWaitReply(s: shortstring);
    34 procedure SendIPCAndWaitReply(s: shortstring);
    35 procedure SendIPCTimeInc;
    35 procedure SendIPCTimeInc;
    36 procedure SendKeepAliveMessage(Lag: Longword);
    36 procedure SendKeepAliveMessage(Lag: Longword);
    37 procedure LoadRecordFromFile(fileName: shortstring);
    37 procedure LoadRecordFromFile(fileName: shortstring);
       
    38 procedure SendStat(sit: TStatInfoType; s: shortstring);
    38 procedure IPCWaitPongEvent;
    39 procedure IPCWaitPongEvent;
    39 procedure IPCCheckSock;
    40 procedure IPCCheckSock;
    40 procedure InitIPC;
    41 procedure InitIPC;
    41 procedure CloseIPC;
    42 procedure CloseIPC;
    42 procedure NetGetNextCmd;
    43 procedure NetGetNextCmd;
       
    44 procedure doPut(putX, putY: LongInt; fromAI: boolean);
    43 
    45 
    44 implementation
    46 implementation
    45 uses uConsole, uConsts, uWorld, uMisc, uLand, uChat, uTeams;
    47 uses uConsole, uConsts, uVariables, uCommands, uUtils, uDebug;
    46 
    48 
    47 type PCmd = ^TCmd;
    49 type PCmd = ^TCmd;
    48      TCmd = packed record
    50      TCmd = packed record
    49             Next: PCmd;
    51             Next: PCmd;
    50             loTime: Word;
    52             loTime: Word;
    61 
    63 
    62     headcmd: PCmd;
    64     headcmd: PCmd;
    63     lastcmd: PCmd;
    65     lastcmd: PCmd;
    64 
    66 
    65     SendEmptyPacketTicks: LongWord;
    67     SendEmptyPacketTicks: LongWord;
    66 
       
    67 
    68 
    68 function AddCmd(Time: Word; str: shortstring): PCmd;
    69 function AddCmd(Time: Word; str: shortstring): PCmd;
    69 var command: PCmd;
    70 var command: PCmd;
    70 begin
    71 begin
    71 new(command);
    72 new(command);
   126      '!': begin {$IFDEF DEBUGFILE}AddFileLog('Ping? Pong!');{$ENDIF}isPonged:= true; end;
   127      '!': begin {$IFDEF DEBUGFILE}AddFileLog('Ping? Pong!');{$ENDIF}isPonged:= true; end;
   127      '?': SendIPC('!');
   128      '?': SendIPC('!');
   128      'e': ParseCommand(copy(s, 2, Length(s) - 1), true);
   129      'e': ParseCommand(copy(s, 2, Length(s) - 1), true);
   129      'E': OutError(copy(s, 2, Length(s) - 1), true);
   130      'E': OutError(copy(s, 2, Length(s) - 1), true);
   130      'W': OutError(copy(s, 2, Length(s) - 1), false);
   131      'W': OutError(copy(s, 2, Length(s) - 1), false);
   131      'M': CheckLandDigest(s);
   132      'M': ParseCommand('landcheck ' + s, true);
   132      'T': case s[2] of
   133      'T': case s[2] of
   133                'L': GameType:= gmtLocal;
   134                'L': GameType:= gmtLocal;
   134                'D': GameType:= gmtDemo;
   135                'D': GameType:= gmtDemo;
   135                'N': GameType:= gmtNet;
   136                'N': GameType:= gmtNet;
   136                'S': GameType:= gmtSave;
   137                'S': GameType:= gmtSave;
   137                else OutError(errmsgIncorrectUse + ' IPC "T" :' + s[2], true) end;
   138                else OutError(errmsgIncorrectUse + ' IPC "T" :' + s[2], true) end;
   138      else
   139      else
   139      loTicks:= SDLNet_Read16(@s[byte(s[0]) - 1]);
   140      loTicks:= SDLNet_Read16(@s[byte(s[0]) - 1]);
   140      AddCmd(loTicks, s);
   141      AddCmd(loTicks, s);
   141      {$IFDEF DEBUGFILE}AddFileLog('IPC in: '+s[1]+' ticks '+inttostr(lastcmd^.loTime));{$ENDIF}
   142      {$IFDEF DEBUGFILE}AddFileLog('IPC in: '+s[1]+' ticks '+IntToStr(lastcmd^.loTime));{$ENDIF}
   142      end
   143      end
   143 end;
   144 end;
   144 
   145 
   145 procedure IPCCheckSock;
   146 procedure IPCCheckSock;
   146 const ss: shortstring = '';
   147 const ss: shortstring = '';
   200         end
   201         end
   201 until i = 0;
   202 until i = 0;
   202 
   203 
   203 close(f)
   204 close(f)
   204 end;
   205 end;
       
   206 
       
   207 procedure SendStat(sit: TStatInfoType; s: shortstring);
       
   208 const stc: array [TStatInfoType] of char = 'rDkKHTPsSB';
       
   209 var buf: shortstring;
       
   210 begin
       
   211 buf:= 'i' + stc[sit] + s;
       
   212 SendIPCRaw(@buf[0], length(buf) + 1)
       
   213 end;
       
   214 
   205 
   215 
   206 procedure SendIPC(s: shortstring);
   216 procedure SendIPC(s: shortstring);
   207 begin
   217 begin
   208 if IPCSock <> nil then
   218 if IPCSock <> nil then
   209     begin
   219     begin
   298         'j': ParseCommand('ljump', true);
   308         'j': ParseCommand('ljump', true);
   299         'J': ParseCommand('hjump', true);
   309         'J': ParseCommand('hjump', true);
   300         ',': ParseCommand('skip', true);
   310         ',': ParseCommand('skip', true);
   301         's': begin
   311         's': begin
   302             s:= copy(headcmd^.str, 2, Pred(headcmd^.len));
   312             s:= copy(headcmd^.str, 2, Pred(headcmd^.len));
   303             AddChatString(s);
   313             ParseCommand('chatmsg ' + s, true);
   304             WriteLnToConsole(s)
   314             WriteLnToConsole(s)
   305             end;
   315             end;
   306         'b': begin
   316         'b': begin
   307             s:= copy(headcmd^.str, 2, Pred(headcmd^.len));
   317             s:= copy(headcmd^.str, 2, Pred(headcmd^.len));
   308             AddChatString(#4 + s);
   318             ParseCommand('chatmsg '#4 + s, true);
   309             WriteLnToConsole(s)
   319             WriteLnToConsole(s)
   310             end;
   320             end;
   311         'F': TeamGone(copy(headcmd^.str, 2, Pred(headcmd^.len)));
   321 // TODO: deprecate 'F'
       
   322         'F': ParseCommand('teamgone ' + copy(headcmd^.str, 2, Pred(headcmd^.len)), true);
   312         'N': begin
   323         'N': begin
   313             tmpflag:= false;
   324             tmpflag:= false;
   314             {$IFDEF DEBUGFILE}AddFileLog('got cmd "N": time '+inttostr(hiTicks shl 16 + headcmd^.loTime)){$ENDIF}
   325             {$IFDEF DEBUGFILE}AddFileLog('got cmd "N": time '+IntToStr(hiTicks shl 16 + headcmd^.loTime)){$ENDIF}
   315             end;
   326             end;
   316         'p': begin
   327         'p': begin
   317             x16:= SDLNet_Read16(@(headcmd^.X));
   328             x16:= SDLNet_Read16(@(headcmd^.X));
   318             y16:= SDLNet_Read16(@(headcmd^.Y));
   329             y16:= SDLNet_Read16(@(headcmd^.Y));
   319             doPut(x16, y16, false)
   330             doPut(x16, y16, false)
   340     end;
   351     end;
   341 
   352 
   342 if (headcmd <> nil) and tmpflag and (not CurrentTeam^.hasGone) then
   353 if (headcmd <> nil) and tmpflag and (not CurrentTeam^.hasGone) then
   343     TryDo(GameTicks < hiTicks shl 16 + headcmd^.loTime,
   354     TryDo(GameTicks < hiTicks shl 16 + headcmd^.loTime,
   344             'oops, queue error. in buffer: ' + headcmd^.cmd +
   355             'oops, queue error. in buffer: ' + headcmd^.cmd +
   345             ' (' + inttostr(GameTicks) + ' > ' +
   356             ' (' + IntToStr(GameTicks) + ' > ' +
   346             inttostr(hiTicks shl 16 + headcmd^.loTime) + ')',
   357             IntToStr(hiTicks shl 16 + headcmd^.loTime) + ')',
   347             true);
   358             true);
   348 
   359 
   349 isInLag:= (headcmd = nil) and tmpflag and (not CurrentTeam^.hasGone);
   360 isInLag:= (headcmd = nil) and tmpflag and (not CurrentTeam^.hasGone);
   350 
   361 
   351 if isInLag then fastUntilLag:= false
   362 if isInLag then fastUntilLag:= false
   352 end;
   363 end;
   353 
   364 
       
   365 procedure chFatalError(var s: shortstring);
       
   366 begin
       
   367     SendIPC('E' + s);
       
   368 end;
       
   369 
       
   370 procedure doPut(putX, putY: LongInt; fromAI: boolean);
       
   371 begin
       
   372 if CheckNoTeamOrHH or isPaused then exit;
       
   373 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   374 bShowFinger:= false;
       
   375 if not CurrentTeam^.ExtDriven and bShowAmmoMenu then
       
   376     begin
       
   377     bSelected:= true;
       
   378     exit
       
   379     end;
       
   380 
       
   381 with CurrentHedgehog^.Gear^,
       
   382     CurrentHedgehog^ do
       
   383     if (State and gstHHChooseTarget) <> 0 then
       
   384         begin
       
   385         isCursorVisible:= false;
       
   386         if not CurrentTeam^.ExtDriven then
       
   387             begin
       
   388             if fromAI then
       
   389                 begin
       
   390                 TargetPoint.X:= putX;
       
   391                 TargetPoint.Y:= putY
       
   392                 end else
       
   393                 begin
       
   394                 TargetPoint.X:= CursorPoint.X - WorldDx;
       
   395                 TargetPoint.Y:= cScreenHeight - CursorPoint.Y - WorldDy;
       
   396                 end;
       
   397             SendIPCXY('p', TargetPoint.X, TargetPoint.Y);
       
   398             end
       
   399         else
       
   400             begin
       
   401             TargetPoint.X:= putX;
       
   402             TargetPoint.Y:= putY
       
   403             end;
       
   404         {$IFDEF DEBUGFILE}AddFilelog('put: ' + inttostr(TargetPoint.X) + ', ' + inttostr(TargetPoint.Y));{$ENDIF}
       
   405         State:= State and not gstHHChooseTarget;
       
   406         if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackingPut) <> 0 then
       
   407             Message:= Message or gmAttack;
       
   408         end
       
   409     else
       
   410         if CurrentTeam^.ExtDriven then
       
   411             OutError('got /put while not being in choose target mode', false)
       
   412 end;
       
   413 
   354 procedure initModule;
   414 procedure initModule;
   355 begin
   415 begin
       
   416     RegisterVariable('fatal', vtCommand, @chFatalError, true );
       
   417 
   356     IPCSock:= nil;
   418     IPCSock:= nil;
   357 
   419 
   358     headcmd:= nil;
   420     headcmd:= nil;
   359     lastcmd:= nil;
   421     lastcmd:= nil;
   360     isPonged:= false;   // was const
   422     isPonged:= false;   // was const