# HG changeset patch # User unc0rr # Date 1160331472 0 # Node ID a03c2d037e240159907622fcd2d4769e13cd7216 # Parent 206aabea22295c3e1d6dd17303371e4873e97924 Bots are in the same thread as game. Fixes FreePascal issues. diff -r 206aabea2229 -r a03c2d037e24 hedgewars/SDLh.pas --- a/hedgewars/SDLh.pas Thu Oct 05 20:13:51 2006 +0000 +++ b/hedgewars/SDLh.pas Sun Oct 08 18:17:52 2006 +0000 @@ -110,7 +110,7 @@ r: Byte; g: Byte; b: Byte; - a: Byte; + unused: Byte; end; PSDL_RWops = ^TSDL_RWops; @@ -174,9 +174,6 @@ PByteArray = ^TByteArray; TByteArray = array[0..32767] of Byte; - PSDL_Thread = Pointer; - PSDL_mutex = Pointer; - function SDL_Init(flags: Longword): integer; cdecl; external SDLLibName; procedure SDL_Quit; cdecl; external SDLLibName; @@ -220,13 +217,6 @@ procedure SDL_WM_SetCaption(title: PChar; icon: PChar); cdecl; external SDLLibName; -function SDL_CreateThread(fn: pointer; data: pointer): PSDL_Thread; cdecl; external SDLLibName; -procedure SDL_WaitThread(thread: PSDL_Thread; status: PLongInt); cdecl; external SDLLibName; -function SDL_CreateMutex: PSDL_mutex; cdecl; external SDLLibName; -procedure SDL_DestroyMutex(mutex: PSDL_mutex); cdecl; external SDLLibName; -function SDL_LockMutex(mutex: PSDL_mutex): integer; cdecl; external SDLLibName name 'SDL_mutexP'; -function SDL_UnlockMutex(mutex: PSDL_mutex): integer; cdecl; external SDLLibName name 'SDL_mutexV'; - (* TTF *) const {$IFDEF WIN32} diff -r 206aabea2229 -r a03c2d037e24 hedgewars/uAI.pas --- a/hedgewars/uAI.pas Thu Oct 05 20:13:51 2006 +0000 +++ b/hedgewars/uAI.pas Sun Oct 08 18:17:52 2006 +0000 @@ -19,27 +19,21 @@ unit uAI; interface {$INCLUDE options.inc} -procedure ProcessBot; +procedure ProcessBot(FrameNo: Longword); procedure FreeActionsList; implementation -uses uTeams, uConsts, SDLh, uAIMisc, uGears, uAIAmmoTests, uAIActions, uMisc; +uses uTeams, uConsts, SDLh, uAIMisc, uGears, uAIAmmoTests, uAIActions, uMisc, + uAIThinkStack, uConsole; var BestActions: TActions; - ThinkThread: PSDL_Thread = nil; - StopThinking: boolean; CanUseAmmo: array [TAmmoType] of boolean; + AIThinkStart: Longword; + isThinking: boolean = false; procedure FreeActionsList; begin -{$IFDEF DEBUGFILE}AddFileLog('FreeActionsList called');{$ENDIF} -if ThinkThread <> nil then - begin - {$IFDEF DEBUGFILE}AddFileLog('Waiting AI thread to finish');{$ENDIF} - StopThinking:= true; - SDL_WaitThread(ThinkThread, nil); - ThinkThread:= nil - end; +isThinking:= false; BestActions.Count:= 0; BestActions.Pos:= 0 end; @@ -92,206 +86,160 @@ end; if a = High(TAmmoType) then a:= Low(TAmmoType) else inc(a) - until (a = aa) or (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].AttacksNum > 0) + until (a = aa) or (PHedgehog(Me.Hedgehog).AttacksNum > 0) end end; procedure Walk(Me: PGear); const FallPixForBranching = cHHRadius * 2 + 8; - cBranchStackSize = 12; -type TStackEntry = record - WastedTicks: Longword; - MadeActions: TActions; - Hedgehog: TGear; - end; - -var Stack: record - Count: Longword; - States: array[0..Pred(cBranchStackSize)] of TStackEntry; - end; - - function Push(Ticks: Longword; const Actions: TActions; const Me: TGear; Dir: integer): boolean; - begin - Result:= (Stack.Count < cBranchStackSize) and (Actions.Count < MAXACTIONS - 5); - if Result then - with Stack.States[Stack.Count] do - begin - WastedTicks:= Ticks; - MadeActions:= Actions; - Hedgehog:= Me; - Hedgehog.Message:= Dir; - inc(Stack.Count) - end - end; - - procedure Pop(out Ticks: Longword; out Actions: TActions; out Me: TGear); - begin - dec(Stack.Count); - with Stack.States[Stack.Count] do - begin - Ticks:= WastedTicks; - Actions:= MadeActions; - Me:= Hedgehog - end - end; - - function PosInThinkStack(Me: PGear): boolean; - var i: Longword; - begin - i:= 0; - Result:= false; - while (i < Stack.Count) and not Result do - begin - Result:= (abs(Stack.States[i].Hedgehog.X - Me.X) + - abs(Stack.States[i].Hedgehog.Y - Me.Y) <= 2) - and (Stack.States[i].Hedgehog.Message = Me.Message); - inc(i) - end - end; - - var Actions: TActions; - ticks, maxticks, steps, BotLevel, tmp: Longword; - BaseRate, BestRate, Rate: integer; + ticks, maxticks, steps, BotLevel: Longword; + BaseRate, Rate: integer; GoInfo: TGoInfo; CanGo: boolean; AltMe: TGear; begin -Actions.Count:= 0; -Actions.Pos:= 0; -Actions.Score:= 0; -Stack.Count:= 0; BotLevel:= PHedgehog(Me.Hedgehog).BotLevel; -tmp:= random(2) + 1; -Push(0, Actions, Me^, tmp); -Push(0, Actions, Me^, tmp xor 3); - if (Me.State and gstAttacked) = 0 then maxticks:= max(0, TurnTimeLeft - 5000 - 4000 * BotLevel) else maxticks:= TurnTimeLeft; -if (Me.State and gstAttacked) = 0 then TestAmmos(Actions, Me); -BestRate:= RatePlace(Me); -BaseRate:= max(BestRate, 0); + +BaseRate:= max(RatePlace(Me), 0); -while (Stack.Count > 0) and not StopThinking do - begin - Pop(ticks, Actions, Me^); - +repeat + if not Pop(ticks, Actions, Me^) then + begin + isThinking:= false; + exit + end; AddAction(Actions, Me.Message, aim_push, 250); AddAction(Actions, aia_WaitX, round(Me.X), 0); AddAction(Actions, Me.Message, aim_release, 0); steps:= 0; - while (not StopThinking) and (not PosInThinkStack(Me)) do + while not PosInThinkStack(Me) do begin + if SDL_GetTicks - AIThinkStart > 3 then + begin + writetoconsole(inttostr(SDL_GetTicks - AIThinkStart) + ' '); + dec(Actions.Count, 3); + Push(ticks, Actions, Me^, Me^.Message); + exit + end; + CanGo:= HHGo(Me, @AltMe, GoInfo); inc(ticks, GoInfo.Ticks); if ticks > maxticks then break; if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support if Push(ticks, Actions, AltMe, Me^.Message) then - with Stack.States[Pred(Stack.Count)] do + with ThinkStack.States[Pred(ThinkStack.Count)] do begin AddAction(MadeActions, aia_HJump, 0, 305); AddAction(MadeActions, aia_HJump, 0, 350); end; if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support if Push(ticks, Actions, AltMe, Me^.Message) then - with Stack.States[Pred(Stack.Count)] do + with ThinkStack.States[Pred(ThinkStack.Count)] do AddAction(MadeActions, aia_LJump, 0, 305); if not CanGo then break; inc(steps); Actions.actions[Actions.Count - 2].Param:= round(Me.X); Rate:= RatePlace(Me); - if Rate > BestRate then + if Rate > BaseRate then begin BestActions:= Actions; - BestRate:= Rate; - Me.State:= Me.State or gstAttacked // we have better place, go there and don't use ammo + BestActions.Score:= 1; + isThinking:= false; + exit end - else if Rate < BestRate then break; + else if Rate < BaseRate then break; if ((Me.State and gstAttacked) = 0) and ((steps mod 4) = 0) then TestAmmos(Actions, Me); if GoInfo.FallPix >= FallPixForBranching then Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right end; - - if BestRate > BaseRate then exit - end +until false end; -procedure Think(Me: PGear); cdecl; +procedure Think(Me: PGear); var BackMe, WalkMe: TGear; - StartTicks: Longword; +// StartTicks: Longword; begin -StartTicks:= GameTicks; -BestActions.Count:= 0; -BestActions.Pos:= 0; -BestActions.Score:= Low(integer); +AIThinkStart:= SDL_GetTicks; BackMe:= Me^; WalkMe:= BackMe; if (Me.State and gstAttacked) = 0 then if Targets.Count > 0 then begin Walk(@WalkMe); - if (StartTicks > GameTicks - 1500) and not StopThinking then SDL_Delay(2000); - if BestActions.Score < -1023 then + if not isThinking then begin - BestActions.Count:= 0; - AddAction(BestActions, aia_Skip, 0, 250); - end; + if BestActions.Score < -1023 then + begin + BestActions.Count:= 0; + AddAction(BestActions, aia_Skip, 0, 250); + end; + Me.State:= Me.State and not gstHHThinking + end end else else begin - Walk(@WalkMe); - while (not StopThinking) and (BestActions.Count = 0) do - begin - SDL_Delay(100); - FillBonuses(true); - WalkMe:= BackMe; - Walk(@WalkMe) - end - end; -Me.State:= Me.State and not gstHHThinking + FillBonuses(true); + Walk(@WalkMe) + end end; procedure StartThink(Me: PGear); var a: TAmmoType; + tmp: integer; begin if ((Me.State and gstAttacking) <> 0) or isInMultiShoot then exit; +ThinkingHH:= Me; +isThinking:= true; + +ClearThinkStack; + Me.State:= Me.State or gstHHThinking; Me.Message:= 0; -StopThinking:= false; -ThinkingHH:= Me; FillTargets; if Targets.Count = 0 then begin OutError('AI: no targets!?'); exit end; + FillBonuses((Me.State and gstAttacked) <> 0); + for a:= Low(TAmmoType) to High(TAmmoType) do CanUseAmmo[a]:= Assigned(AmmoTests[a]) and HHHasAmmo(PHedgehog(Me.Hedgehog), a); -{$IFDEF DEBUGFILE}AddFileLog('Enter Think Thread');{$ENDIF} -ThinkThread:= SDL_CreateThread(@Think, Me) + +BestActions.Count:= 0; +BestActions.Pos:= 0; +BestActions.Score:= 0; +tmp:= random(2) + 1; +Push(0, BestActions, Me^, tmp); +Push(0, BestActions, Me^, tmp xor 3); +BestActions.Score:= Low(integer); + +Think(Me) end; -procedure ProcessBot; -const StartTicks: Longword = 0; +procedure ProcessBot(FrameNo: Longword); +const LastFrameNo: Longword = 0; begin +if FrameNo = LastFrameNo then exit; +LastFrameNo:= FrameNo; with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do if (Gear <> nil) and ((Gear.State and gstHHDriven) <> 0) and (TurnTimeLeft < cHedgehogTurnTime - 50) then - if ((Gear.State and gstHHThinking) = 0) then - if (BestActions.Pos >= BestActions.Count) then - begin - StartThink(Gear); - StartTicks:= GameTicks - end else ProcessAction(BestActions, Gear) - else if (GameTicks - StartTicks) > cMaxAIThinkTime then StopThinking:= true + if not isThinking then + if (BestActions.Pos >= BestActions.Count) then StartThink(Gear) + else ProcessAction(BestActions, Gear) + else Think(Gear) end; end. diff -r 206aabea2229 -r a03c2d037e24 hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Thu Oct 05 20:13:51 2006 +0000 +++ b/hedgewars/uAIMisc.pas Sun Oct 08 18:17:52 2006 +0000 @@ -109,7 +109,6 @@ begin bonuses.Count:= 0; MyColor:= PHedgehog(ThinkingHH.Hedgehog).Team.Color; -SDL_LockMutex(GearsListMutex); Gear:= GearsList; while Gear <> nil do begin @@ -127,7 +126,6 @@ end; Gear:= Gear.NextGear end; -SDL_UnlockMutex(GearsListMutex); if isAfterAttack and (KnownExplosion.Radius > 0) then with KnownExplosion do AddBonus(X, Y, Radius + 10, -Radius); diff -r 206aabea2229 -r a03c2d037e24 hedgewars/uAIThinkStack.pas --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/uAIThinkStack.pas Sun Oct 08 18:17:52 2006 +0000 @@ -0,0 +1,90 @@ +(* + * Hedgewars, a worms-like game + * Copyright (c) 2006 Andrey Korotaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + *) + +unit uAIThinkStack; +interface +uses uAIActions, uGears; +{$INCLUDE options.inc} +const cBranchStackSize = 12; +type TStackEntry = record + WastedTicks: Longword; + MadeActions: TActions; + Hedgehog: TGear; + end; + +var ThinkStack: record + Count: Longword; + States: array[0..Pred(cBranchStackSize)] of TStackEntry; + end; + +function Push(Ticks: Longword; const Actions: TActions; const Me: TGear; Dir: integer): boolean; +function Pop(out Ticks: Longword; out Actions: TActions; out Me: TGear): boolean; +function PosInThinkStack(Me: PGear): boolean; +procedure ClearThinkStack; + +implementation + +function Push(Ticks: Longword; const Actions: TActions; const Me: TGear; Dir: integer): boolean; +begin +Result:= (ThinkStack.Count < cBranchStackSize) and (Actions.Count < MAXACTIONS - 5); +if Result then + with ThinkStack.States[ThinkStack.Count] do + begin + WastedTicks:= Ticks; + MadeActions:= Actions; + Hedgehog:= Me; + Hedgehog.Message:= Dir; + inc(ThinkStack.Count) + end +end; + +function Pop(out Ticks: Longword; out Actions: TActions; out Me: TGear): boolean; +begin +Result:= ThinkStack.Count > 0; +if Result then + begin + dec(ThinkStack.Count); + with ThinkStack.States[ThinkStack.Count] do + begin + Ticks:= WastedTicks; + Actions:= MadeActions; + Me:= Hedgehog + end + end +end; + +function PosInThinkStack(Me: PGear): boolean; +var i: Longword; +begin +i:= 0; +Result:= false; +while (i < ThinkStack.Count) and not Result do + begin + Result:= (abs(ThinkStack.States[i].Hedgehog.X - Me.X) + + abs(ThinkStack.States[i].Hedgehog.Y - Me.Y) <= 2) + and (ThinkStack.States[i].Hedgehog.Message = Me.Message); + inc(i) + end +end; + +procedure ClearThinkStack; +begin +ThinkStack.Count:= 0 +end; + +end. diff -r 206aabea2229 -r a03c2d037e24 hedgewars/uGame.pas --- a/hedgewars/uGame.pas Thu Oct 05 20:13:51 2006 +0000 +++ b/hedgewars/uGame.pas Sun Oct 08 18:17:52 2006 +0000 @@ -53,7 +53,7 @@ if not CurrentTeam.ExtDriven then begin with CurrentTeam^ do - if Hedgehogs[CurrHedgehog].BotLevel <> 0 then ProcessBot; + if Hedgehogs[CurrHedgehog].BotLevel <> 0 then ProcessBot(Frames); ProcessGears end else begin diff -r 206aabea2229 -r a03c2d037e24 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Thu Oct 05 20:13:51 2006 +0000 +++ b/hedgewars/uGears.pas Sun Oct 08 18:17:52 2006 +0000 @@ -60,7 +60,6 @@ var CurAmmoGear: PGear = nil; GearsList: PGear = nil; - GearsListMutex: PSDL_mutex; implementation uses uWorld, uMisc, uStore, uConsole, uSound, uTeams, uRandom, uCollisions, @@ -222,14 +221,12 @@ Result.Tag:= Y end; end; -SDL_LockMutex(GearsListMutex); if GearsList = nil then GearsList:= Result else begin GearsList.PrevGear:= Result; Result.NextGear:= GearsList; GearsList:= Result - end; -SDL_UnlockMutex(GearsListMutex) + end end; procedure DeleteGear(Gear: PGear); @@ -253,7 +250,6 @@ RecountTeamHealth(team); end; {$IFDEF DEBUGFILE}AddFileLog('DeleteGear: handle = '+inttostr(integer(Gear)));{$ENDIF} -SDL_LockMutex(GearsListMutex); if CurAmmoGear = Gear then CurAmmoGear:= nil; if FollowGear = Gear then FollowGear:= nil; if Gear.NextGear <> nil then Gear.NextGear.PrevGear:= Gear.PrevGear; @@ -262,7 +258,6 @@ GearsList:= Gear^.NextGear; if GearsList <> nil then GearsList.PrevGear:= nil end; -SDL_UnlockMutex(GearsListMutex); Dispose(Gear) end; @@ -781,10 +776,8 @@ end; initialization -GearsListMutex:= SDL_CreateMutex; finalization FreeGearsList; -SDL_DestroyMutex(GearsListMutex); end. diff -r 206aabea2229 -r a03c2d037e24 hedgewars/uLand.pas --- a/hedgewars/uLand.pas Thu Oct 05 20:13:51 2006 +0000 +++ b/hedgewars/uLand.pas Sun Oct 08 18:17:52 2006 +0000 @@ -476,13 +476,13 @@ AddProgress; with PixelFormat^ do - tmpsurf:= SDL_CreateRGBSurface(SDL_HWSURFACE, 2048, 1024, BitsPerPixel, RMask, GMask, BMask, 0); + tmpsurf:= SDL_CreateRGBSurface(SDL_HWSURFACE, 2048, 1024, BitsPerPixel, RMask, GMask, BMask, AMask); TryDo(tmpsurf <> nil, 'Error creating pre-land surface', true); ColorizeLand(tmpsurf); AddProgress; AddBorder(tmpsurf); with PixelFormat^ do - LandSurface:= SDL_CreateRGBSurface(SDL_HWSURFACE, 2048, 1024, BitsPerPixel, RMask, GMask, BMask, 0); + LandSurface:= SDL_CreateRGBSurface(SDL_HWSURFACE, 2048, 1024, BitsPerPixel, RMask, GMask, BMask, AMask); TryDo(LandSurface <> nil, 'Error creating land surface', true); SDL_FillRect(LandSurface, nil, 0); AddProgress; @@ -502,7 +502,7 @@ p:= TeamsList; TryDo(p <> nil, 'No teams on map!', true); with PixelFormat^ do - LandSurface:= SDL_CreateRGBSurface(SDL_HWSURFACE, 2048, 1024, BitsPerPixel, RMask, GMask, BMask, 0); + LandSurface:= SDL_CreateRGBSurface(SDL_HWSURFACE, 2048, 1024, BitsPerPixel, RMask, GMask, BMask, AMask); SDL_FillRect(LandSurface, nil, 0); tmpsurf:= LoadImage(Pathz[ptForts] + '/' + p.FortName + 'L', false); BlitImageAndGenerateCollisionInfo(0, 0, tmpsurf, LandSurface); diff -r 206aabea2229 -r a03c2d037e24 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Thu Oct 05 20:13:51 2006 +0000 +++ b/hedgewars/uStore.pas Sun Oct 08 18:17:52 2006 +0000 @@ -50,7 +50,7 @@ procedure StoreInit; begin -StoreSurface:= SDL_CreateRGBSurface(SDL_HWSURFACE, 576, 1024, cBits, PixelFormat.RMask, PixelFormat.GMask, PixelFormat.BMask, 0); +StoreSurface:= SDL_CreateRGBSurface(SDL_HWSURFACE, 576, 1024, cBits, PixelFormat.RMask, PixelFormat.GMask, PixelFormat.BMask, PixelFormat.AMask); TryDo( StoreSurface <> nil, errmsgCreateSurface + ': store' , true); SDL_FillRect(StoreSurface, nil, 0); @@ -107,7 +107,6 @@ clr.r:= Color shr 16; clr.g:= (Color shr 8) and $FF; clr.b:= Color and $FF; -clr.a:= $FF; tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, PChar(s), clr); Result.x:= X + 3; Result.y:= Y + 1; @@ -251,14 +250,7 @@ TryDo(IOResult = 0, msgFailed, true); WriteLnToConsole(msgOK); val(s, cExplosionBorderColor, c); - if cFullScreen then - cExplosionBorderColor:= SDL_MapRGB(PixelFormat, (cExplosionBorderColor shr 16) and $FF, - (cExplosionBorderColor shr 8) and $FF, - cExplosionBorderColor and $FF) - else - cExplosionBorderColor:= SDL_MapRGB(LandSurface.format, (cExplosionBorderColor shr 16) and $FF, - (cExplosionBorderColor shr 8) and $FF, - cExplosionBorderColor and $FF) + AdjustColor(cExplosionBorderColor); end; begin @@ -382,7 +374,6 @@ clr.r:= $FF; clr.g:= $FF; clr.b:= $FF; -clr.a:= $FF; tmpsurf:= TTF_RenderUTF8_Solid(Fontz[Font].Handle, PChar(s), clr); SDL_UpperBlit(tmpsurf, nil, Surface, @r); SDL_FreeSurface(tmpsurf) @@ -439,7 +430,7 @@ var w, h: integer; begin TTF_SizeUTF8(Fontz[font].Handle, PChar(s), w, h); -Result:= SDL_CreateRGBSurface(SDL_HWSURFACE, w + 6, h + 2, cBits, PixelFormat.RMask, PixelFormat.GMask, PixelFormat.BMask, 0); +Result:= SDL_CreateRGBSurface(SDL_HWSURFACE, w + 6, h + 2, cBits, PixelFormat.RMask, PixelFormat.GMask, PixelFormat.BMask, PixelFormat.AMask); TryDo(Result <> nil, 'RenderString: fail to create surface', true); WriteInRoundRect(Result, 0, 0, Color, font, s); TryDo(SDL_SetColorKey(Result, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0) = 0, errmsgTransparentSet, true) diff -r 206aabea2229 -r a03c2d037e24 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Thu Oct 05 20:13:51 2006 +0000 +++ b/hedgewars/uWorld.pas Sun Oct 08 18:17:52 2006 +0000 @@ -35,11 +35,11 @@ bShowAmmoMenu: boolean = false; bSelected: boolean = false; bShowFinger: boolean = false; + Frames: Longword = 0; implementation uses uStore, uMisc, uTeams, uIO, uConsole, uKeys, uLocale, uSound; const RealTicks: Longword = 0; - Frames: Longword = 0; FPS: Longword = 0; CountTicks: Longword = 0; SoundTimerTicks: Longword = 0; diff -r 206aabea2229 -r a03c2d037e24 tools/runhelper.dpr --- a/tools/runhelper.dpr Thu Oct 05 20:13:51 2006 +0000 +++ b/tools/runhelper.dpr Sun Oct 08 18:17:52 2006 +0000 @@ -48,7 +48,7 @@ begin Send('TL'); Send('e$gmflags 1'); -Send('eseed 31337'); +Send('eseed -=31337=-'); Send('etheme steel'); Send('eaddteam'); Send('ename team "C0CuCKAzZz"'); @@ -143,7 +143,7 @@ end; begin -WriteLn('run hwengine 640 480 16 46631 0 1 ru.txt'); +WriteLn('run hwengine 640 480 16 46631 0 1 ru.txt 128'); SDL_Init(0); SDLNet_Init; ip.host:= 0;