hedgewars/hwengine.pas
changeset 2947 803b277e4894
parent 2905 f3c79f7193a9
child 2948 3f21a9dc93d0
equal deleted inserted replaced
2946:1d9e0a541c62 2947:803b277e4894
     1  (*
     1 (*
     2  * Hedgewars, a free turn based strategy game
     2 * Hedgewars, a free turn based strategy game
     3  * Copyright (c) 2004-2007 Andrey Korotaev <unC0Rr@gmail.com>
     3 * Copyright (c) 2004-2007 Andrey Korotaev <unC0Rr@gmail.com>
     4  *
     4 *
     5  * This program is free software; you can redistribute it and/or modify
     5 * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6 * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7 * the Free Software Foundation; version 2 of the License
     8  *
     8 *
     9  * This program is distributed in the hope that it will be useful,
     9 * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    12 * GNU General Public License for more details.
    13  *
    13 *
    14  * You should have received a copy of the GNU General Public License
    14 * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    15 * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    17  *)
    17 *)
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 {$IFDEF WIN32}
    21 {$IFDEF WIN32}
    22 {$R hwengine.rc}
    22 {$R hwengine.rc}
    27 interface
    27 interface
    28 {$ELSE}
    28 {$ELSE}
    29 program hwengine;
    29 program hwengine;
    30 {$ENDIF}
    30 {$ENDIF}
    31 uses	SDLh in 'SDLh.pas',
    31 uses	SDLh in 'SDLh.pas',
    32 	uConsts in 'uConsts.pas',
    32     uConsts in 'uConsts.pas',
    33 	uGame in 'uGame.pas',
    33     uGame in 'uGame.pas',
    34 	uMisc in 'uMisc.pas',
    34     uMisc in 'uMisc.pas',
    35 	uStore in 'uStore.pas',
    35     uStore in 'uStore.pas',
    36 	uWorld in 'uWorld.pas',
    36     uWorld in 'uWorld.pas',
    37 	uIO in 'uIO.pas',
    37     uIO in 'uIO.pas',
    38 	uGears in 'uGears.pas',
    38     uGears in 'uGears.pas',
    39 	uVisualGears in 'uVisualGears.pas',
    39     uVisualGears in 'uVisualGears.pas',
    40 	uConsole in 'uConsole.pas',
    40     uConsole in 'uConsole.pas',
    41 	uKeys in 'uKeys.pas',
    41     uKeys in 'uKeys.pas',
    42 	uTeams in 'uTeams.pas',
    42     uTeams in 'uTeams.pas',
    43 	uSound in 'uSound.pas',
    43     uSound in 'uSound.pas',
    44 	uRandom in 'uRandom.pas',
    44     uRandom in 'uRandom.pas',
    45 	uAI in 'uAI.pas',
    45     uAI in 'uAI.pas',
    46 	uAIMisc in 'uAIMisc.pas',
    46     uAIMisc in 'uAIMisc.pas',
    47 	uAIAmmoTests in 'uAIAmmoTests.pas',
    47     uAIAmmoTests in 'uAIAmmoTests.pas',
    48 	uAIActions in 'uAIActions.pas',
    48     uAIActions in 'uAIActions.pas',
    49 	uCollisions in 'uCollisions.pas',
    49     uCollisions in 'uCollisions.pas',
    50 	uLand in 'uLand.pas',
    50     uLand in 'uLand.pas',
    51 	uLandTemplates in 'uLandTemplates.pas',
    51     uLandTemplates in 'uLandTemplates.pas',
    52 	uLandObjects in 'uLandObjects.pas',
    52     uLandObjects in 'uLandObjects.pas',
    53 	uLandGraphics in 'uLandGraphics.pas',
    53     uLandGraphics in 'uLandGraphics.pas',
    54 	uLocale in 'uLocale.pas',
    54     uLocale in 'uLocale.pas',
    55 	uAmmos in 'uAmmos.pas',
    55     uAmmos in 'uAmmos.pas',
    56 	uSHA in 'uSHA.pas',
    56     uSHA in 'uSHA.pas',
    57 	uFloat in 'uFloat.pas',
    57     uFloat in 'uFloat.pas',
    58 	uStats in 'uStats.pas',
    58     uStats in 'uStats.pas',
    59 	uChat in 'uChat.pas',
    59     uChat in 'uChat.pas',
    60 	uTriggers in 'uTriggers.pas',
    60     uTriggers in 'uTriggers.pas',
    61 	uLandTexture in 'uLandTexture.pas',
    61     uLandTexture in 'uLandTexture.pas',
    62 	uScript in 'uScript.pas',
    62     uScript in 'uScript.pas',
    63 	{$IFDEF IPHONEOS}PascalExports in 'PascalExports.pas',{$ENDIF}
    63     {$IFDEF IPHONEOS}PascalExports in 'PascalExports.pas',{$ENDIF}
    64 	sysutils;
    64     sysutils;
    65 
    65 
    66 // also: GSHandlers.inc
    66 // also: GSHandlers.inc
    67 //       CCHandlers.inc
    67 //       CCHandlers.inc
    68 //       HHHandlers.inc
    68 //       HHHandlers.inc
    69 //       SinTable.inc
    69 //       SinTable.inc
    90 procedure DoTimer(Lag: LongInt);
    90 procedure DoTimer(Lag: LongInt);
    91 {$IFNDEF IPHONEOS}
    91 {$IFNDEF IPHONEOS}
    92 var s: shortstring;
    92 var s: shortstring;
    93 {$ENDIF}
    93 {$ENDIF}
    94 begin
    94 begin
    95 	inc(RealTicks, Lag);
    95     inc(RealTicks, Lag);
    96 
    96 
    97 	case GameState of
    97     case GameState of
    98 		gsLandGen: begin
    98         gsLandGen: begin
    99 				GenMap;
    99                 GenMap;
   100 				GameState:= gsStart;
   100                 GameState:= gsStart;
   101 				end;
   101                 end;
   102 		gsStart: begin
   102         gsStart: begin
   103 				if HasBorder then DisableSomeWeapons;
   103                 if HasBorder then DisableSomeWeapons;
   104 				AddClouds;
   104                 AddClouds;
   105 				AssignHHCoords;
   105                 AssignHHCoords;
   106 				AddMiscGears;
   106                 AddMiscGears;
   107 				StoreLoad;
   107                 StoreLoad;
   108 				InitWorld;
   108                 InitWorld;
   109 				ResetKbd;
   109                 ResetKbd;
   110 				SoundLoad;
   110                 SoundLoad;
   111 				if GameType = gmtSave then
   111                 if GameType = gmtSave then
   112 					begin
   112                     begin
   113 					isSEBackup:= isSoundEnabled;
   113                     isSEBackup:= isSoundEnabled;
   114 					isSoundEnabled:= false
   114                     isSoundEnabled:= false
   115 					end;
   115                     end;
   116 				FinishProgress;
   116                 FinishProgress;
   117 				PlayMusic;
   117                 PlayMusic;
   118 				SetScale(zoom);
   118                 SetScale(zoom);
   119 				ScriptCall('onGameStart');
   119                 ScriptCall('onGameStart');
   120 				GameState:= gsGame;
   120                 GameState:= gsGame;
   121 				end;
   121                 end;
   122 		gsConfirm,
   122         gsConfirm,
   123 		gsGame: begin
   123         gsGame: begin
   124 				DrawWorld(Lag); // never place between ProcessKbd and DoGameTick - bugs due to /put cmd and isCursorVisible
   124                 DrawWorld(Lag); // never place between ProcessKbd and DoGameTick - bugs due to /put cmd and isCursorVisible
   125 				ProcessKbd;
   125                 ProcessKbd;
   126 				DoGameTick(Lag);
   126                 DoGameTick(Lag);
   127 				ProcessVisualGears(Lag);
   127                 ProcessVisualGears(Lag);
   128 				end;
   128                 end;
   129 		gsChat: begin
   129         gsChat: begin
   130 				DrawWorld(Lag);
   130                 DrawWorld(Lag);
   131 				DoGameTick(Lag);
   131                 DoGameTick(Lag);
   132 				ProcessVisualGears(Lag);
   132                 ProcessVisualGears(Lag);
   133 				end;
   133                 end;
   134 		gsExit: begin
   134         gsExit: begin
   135 				isTerminated:= true;
   135                 isTerminated:= true;
   136 				end;
   136                 end;
   137 		end;
   137         end;
   138 
   138 
   139 	SDL_GL_SwapBuffers();
   139     SDL_GL_SwapBuffers();
   140 {$IFDEF SDL13}
   140 {$IFDEF SDL13}
   141 	SDL_RenderPresent();
   141     SDL_RenderPresent();
   142 {$ENDIF}
   142 {$ENDIF}
   143 {$IFNDEF IPHONEOS}
   143 {$IFNDEF IPHONEOS}
   144 	// not going to make captures on the iPhone
   144     // not going to make captures on the iPhone
   145 	if flagMakeCapture then
   145     if flagMakeCapture then
   146 	begin
   146     begin
   147 		flagMakeCapture:= false;
   147         flagMakeCapture:= false;
   148 		s:= 'hw_' + FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now()) + inttostr(GameTicks);
   148         s:= 'hw_' + FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now()) + inttostr(GameTicks);
   149 		WriteLnToConsole('Saving ' + s + '...');
   149         WriteLnToConsole('Saving ' + s + '...');
   150 		MakeScreenshot(s);
   150         MakeScreenshot(s);
   151 		//SDL_SaveBMP_RW(SDLPrimSurface, SDL_RWFromFile(Str2PChar(s), 'wb'), 1)
   151         //SDL_SaveBMP_RW(SDLPrimSurface, SDL_RWFromFile(Str2PChar(s), 'wb'), 1)
   152 	end;
   152     end;
   153 {$ENDIF}
   153 {$ENDIF}
   154 end;
   154 end;
   155 
   155 
   156 ////////////////////
   156 ////////////////////
   157 procedure OnDestroy;
   157 procedure OnDestroy;
   158 begin
   158 begin
   159 	WriteLnToConsole('Freeing resources...');
   159     WriteLnToConsole('Freeing resources...');
   160 	if isSoundEnabled then ReleaseSound();
   160     if isSoundEnabled then ReleaseSound();
   161 	StoreRelease();
   161     StoreRelease();
   162 	FreeLand();
   162     FreeLand();
   163 	ControllerClose();
   163     ControllerClose();
   164 	SendKB();
   164     SendKB();
   165 	CloseIPC();
   165     CloseIPC();
   166 	TTF_Quit();
   166     TTF_Quit();
   167 	{$IFDEF SDL13}SDL_VideoQuit();{$ENDIF}
   167     {$IFDEF SDL13}SDL_VideoQuit();{$ENDIF}
   168 	SDL_Quit();
   168     SDL_Quit();
   169 	{$IFDEF IPHONEOS}
   169     {$IFDEF IPHONEOS}
   170 	freeEverything();
   170     freeEverything();
   171 	{$ENDIF}
   171     {$ENDIF}
   172 	exit();
   172     exit();
   173 end;
   173 end;
   174 
   174 
   175 ///////////////////
   175 ///////////////////
   176 procedure MainLoop; 
   176 procedure MainLoop; 
   177 var PrevTime, CurrTime: Longword;
   177 var PrevTime, CurrTime: Longword;
   178     {$IFNDEF IPHONEOS}event: TSDL_Event;{$ENDIF}
   178     {$IFNDEF IPHONEOS}event: TSDL_Event;{$ENDIF}
   179 begin
   179 begin
   180 	PrevTime:= SDL_GetTicks;
   180     PrevTime:= SDL_GetTicks;
   181 	repeat
   181     repeat
   182 {$IFNDEF IPHONEOS}
   182 {$IFNDEF IPHONEOS}
   183 // have to remove this cycle because otherwise it segfaults at exit
   183 // have to remove this cycle because otherwise it segfaults at exit
   184 		while SDL_PollEvent(@event) <> 0 do
   184         while SDL_PollEvent(@event) <> 0 do
   185 		begin
   185         begin
   186 			case event.type_ of
   186             case event.type_ of
   187 				SDL_KEYDOWN: if GameState = gsChat then KeyPressChat(event.key.keysym.unicode);
   187                 SDL_KEYDOWN: if GameState = gsChat then KeyPressChat(event.key.keysym.unicode);
   188 {$IFDEF SDL13}
   188 {$IFDEF SDL13}
   189 				SDL_WINDOWEVENT:
   189                 SDL_WINDOWEVENT:
   190 {$ELSE}
   190 {$ELSE}
   191 				SDL_ACTIVEEVENT:
   191                 SDL_ACTIVEEVENT:
   192 {$ENDIF}
   192 {$ENDIF}
   193 					if (event.active.state and SDL_APPINPUTFOCUS) <> 0 then
   193                     if (event.active.state and SDL_APPINPUTFOCUS) <> 0 then
   194 						cHasFocus:= event.active.gain = 1;
   194                         cHasFocus:= event.active.gain = 1;
   195 				//SDL_VIDEORESIZE: Resize(max(event.resize.w, 600), max(event.resize.h, 450));
   195                 //SDL_VIDEORESIZE: Resize(max(event.resize.w, 600), max(event.resize.h, 450));
   196 				SDL_MOUSEBUTTONDOWN: if event.button.button = SDL_BUTTON_WHEELDOWN then uKeys.wheelDown:= true;
   196                 SDL_MOUSEBUTTONDOWN: if event.button.button = SDL_BUTTON_WHEELDOWN then uKeys.wheelDown:= true;
   197 				SDL_MOUSEBUTTONUP: if event.button.button = SDL_BUTTON_WHEELUP then uKeys.wheelUp:= true;
   197                 SDL_MOUSEBUTTONUP: if event.button.button = SDL_BUTTON_WHEELUP then uKeys.wheelUp:= true;
   198 				SDL_JOYAXISMOTION: ControllerAxisEvent(event.jaxis.which, event.jaxis.axis, event.jaxis.value);
   198                 SDL_JOYAXISMOTION: ControllerAxisEvent(event.jaxis.which, event.jaxis.axis, event.jaxis.value);
   199 				SDL_JOYHATMOTION: ControllerHatEvent(event.jhat.which, event.jhat.hat, event.jhat.value);
   199                 SDL_JOYHATMOTION: ControllerHatEvent(event.jhat.which, event.jhat.hat, event.jhat.value);
   200 				SDL_JOYBUTTONDOWN: ControllerButtonEvent(event.jbutton.which, event.jbutton.button, true);
   200                 SDL_JOYBUTTONDOWN: ControllerButtonEvent(event.jbutton.which, event.jbutton.button, true);
   201 				SDL_JOYBUTTONUP: ControllerButtonEvent(event.jbutton.which, event.jbutton.button, false);
   201                 SDL_JOYBUTTONUP: ControllerButtonEvent(event.jbutton.which, event.jbutton.button, false);
   202 				SDL_QUITEV: isTerminated:= true
   202                 SDL_QUITEV: isTerminated:= true
   203 			end; // end case event.type_ of
   203             end; // end case event.type_ of
   204 		end; // end while SDL_PollEvent(@event) <> 0 do
   204         end; // end while SDL_PollEvent(@event) <> 0 do
   205 {$ENDIF}
   205 {$ENDIF}
   206 		CurrTime:= SDL_GetTicks;
   206         CurrTime:= SDL_GetTicks;
   207 		if PrevTime + cTimerInterval <= CurrTime then
   207         if PrevTime + cTimerInterval <= CurrTime then
   208 		begin
   208         begin
   209 			DoTimer(CurrTime - PrevTime);
   209             DoTimer(CurrTime - PrevTime);
   210 			PrevTime:= CurrTime
   210             PrevTime:= CurrTime
   211 		end else SDL_Delay(1);
   211         end else SDL_Delay(1);
   212 		if isTerminated = false then IPCCheckSock();
   212         if isTerminated = false then IPCCheckSock();
   213 	until isTerminated;
   213     until isTerminated;
   214 
   214 
   215 	exit();
   215     exit();
   216 end;
   216 end;
   217 
   217 
   218 /////////////////////////
   218 /////////////////////////
   219 procedure ShowMainWindow;
   219 procedure ShowMainWindow;
   220 begin
   220 begin
   221 	if cFullScreen then ParseCommand('fullscr 1', true)
   221     if cFullScreen then ParseCommand('fullscr 1', true)
   222 	else ParseCommand('fullscr 0', true);
   222     else ParseCommand('fullscr 0', true);
   223 	SDL_ShowCursor(0)
   223     SDL_ShowCursor(0)
   224 end;
   224 end;
   225 
   225 
   226 ///////////////
   226 ///////////////
   227 {$IFDEF HWLIBRARY}
   227 {$IFDEF HWLIBRARY}
   228 procedure Game(gameArgs: arrayofpchar); cdecl; export;
   228 procedure Game(gameArgs: arrayofpchar); cdecl; export;
   229 {$ELSE}
   229 {$ELSE}
   230 procedure Game;cdecl; export;
   230 procedure Game;cdecl; export;
   231 {$ENDIF}
   231 {$ENDIF}
   232 var	p: TPathType;
   232 var	p: TPathType;
   233 	s: shortstring;
   233     s: shortstring;
   234 begin
   234 begin
   235 {$IFDEF HWLIBRARY}
   235 {$IFDEF HWLIBRARY}
   236 	initEverything();
   236     initEverything();
   237 	Randomize();
   237     Randomize();
   238 
   238 
   239 	cScreenWidth:= 480;
   239     cScreenWidth:= 480;
   240 	cScreenHeight:= 320;
   240     cScreenHeight:= 320;
   241 	cInitWidth:= cScreenWidth;
   241     cInitWidth:= cScreenWidth;
   242 	cInitHeight:= cScreenHeight;
   242     cInitHeight:= cScreenHeight;
   243 	cBits:= 32;
   243     cBits:= 32;
   244 	cFullScreen:= false;
   244     cFullScreen:= false;
   245 	cVSyncInUse:= true;
   245     cVSyncInUse:= true;
   246 	cTimerInterval:= 8;
   246     cTimerInterval:= 8;
   247 	PathPrefix:= 'Data';
   247     PathPrefix:= 'Data';
   248 	cReducedQuality:= false;
   248     cReducedQuality:= false;
   249 	cShowFPS:= true;
   249     cShowFPS:= true;
   250 	cInitVolume:= 100;
   250     cInitVolume:= 100;
   251 
   251 
   252 	UserNick:= gameArgs[0];
   252     UserNick:= gameArgs[0];
   253 	val(gameArgs[1], ipcPort);
   253     val(gameArgs[1], ipcPort);
   254 	isSoundEnabled:= gameArgs[2] = '1';
   254     isSoundEnabled:= gameArgs[2] = '1';
   255 	isMusicEnabled:= gameArgs[3] = '1';
   255     isMusicEnabled:= gameArgs[3] = '1';
   256 	cLocaleFName:= gameArgs[4];
   256     cLocaleFName:= gameArgs[4];
   257 	cAltDamage:= gameArgs[5] = '1';
   257     cAltDamage:= gameArgs[5] = '1';
   258 {$ENDIF}
   258 {$ENDIF}
   259 
   259 
   260 	for p:= Succ(Low(TPathType)) to High(TPathType) do
   260     for p:= Succ(Low(TPathType)) to High(TPathType) do
   261 		if p <> ptMapCurrent then Pathz[p]:= PathPrefix + '/' + Pathz[p];
   261         if p <> ptMapCurrent then Pathz[p]:= PathPrefix + '/' + Pathz[p];
   262 		
   262         
   263 	WriteToConsole('Init SDL... ');
   263     WriteToConsole('Init SDL... ');
   264 	SDLTry(SDL_Init(SDL_INIT_VIDEO) >= 0, true);
   264     SDLTry(SDL_Init(SDL_INIT_VIDEO) >= 0, true);
   265 	WriteLnToConsole(msgOK);
   265     WriteLnToConsole(msgOK);
   266 
   266 
   267 	SDL_EnableUNICODE(1);
   267     SDL_EnableUNICODE(1);
   268 
   268 
   269 	WriteToConsole('Init SDL_ttf... ');
   269     WriteToConsole('Init SDL_ttf... ');
   270 	SDLTry(TTF_Init() <> -1, true);
   270     SDLTry(TTF_Init() <> -1, true);
   271 	WriteLnToConsole(msgOK);
   271     WriteLnToConsole(msgOK);
   272 
   272 
   273 	ShowMainWindow();
   273     ShowMainWindow();
   274 
   274 
   275 	AddProgress();
   275     AddProgress();
   276 
   276 
   277 	ControllerInit(); // has to happen before InitKbdKeyTable to map keys
   277     ControllerInit(); // has to happen before InitKbdKeyTable to map keys
   278 	InitKbdKeyTable();
   278     InitKbdKeyTable();
   279 
   279 
   280 	if recordFileName = '' then
   280     if recordFileName = '' then
   281 		InitIPC;
   281         InitIPC;
   282 	WriteLnToConsole(msgGettingConfig);
   282     WriteLnToConsole(msgGettingConfig);
   283 
   283 
   284 	LoadLocale(Pathz[ptLocale] + '/en.txt');  // Do an initial load with english
   284     LoadLocale(Pathz[ptLocale] + '/en.txt');  // Do an initial load with english
   285 	if cLocaleFName <> 'en.txt' then
   285     if cLocaleFName <> 'en.txt' then
   286         begin
   286         begin
   287         // Try two letter locale first before trying specific locale overrides
   287         // Try two letter locale first before trying specific locale overrides
   288         if (Length(cLocaleFName) > 6) and (Copy(cLocaleFName,1,2)+'.txt' <> 'en.txt') then 
   288         if (Length(cLocaleFName) > 6) and (Copy(cLocaleFName,1,2)+'.txt' <> 'en.txt') then 
   289             LoadLocale(Pathz[ptLocale] + '/' + Copy(cLocaleFName,1,2)+'.txt');
   289             LoadLocale(Pathz[ptLocale] + '/' + Copy(cLocaleFName,1,2)+'.txt');
   290 	    LoadLocale(Pathz[ptLocale] + '/' + cLocaleFName);
   290         LoadLocale(Pathz[ptLocale] + '/' + cLocaleFName);
   291         end;
   291         end;
   292 
   292 
   293 	if recordFileName = '' then
   293     if recordFileName = '' then
   294 		SendIPCAndWaitReply('C')        // ask for game config
   294         SendIPCAndWaitReply('C')        // ask for game config
   295 	else
   295     else
   296 		LoadRecordFromFile(recordFileName);
   296         LoadRecordFromFile(recordFileName);
   297 
   297 
   298 	ScriptOnGameInit;
   298     ScriptOnGameInit;
   299 
   299 
   300 	s:= 'eproto ' + inttostr(cNetProtoVersion);
   300     s:= 'eproto ' + inttostr(cNetProtoVersion);
   301 	SendIPCRaw(@s[0], Length(s) + 1); // send proto version
   301     SendIPCRaw(@s[0], Length(s) + 1); // send proto version
   302 
   302 
   303 	InitTeams();
   303     InitTeams();
   304 	AssignStores();
   304     AssignStores();
   305 
   305 
   306 	if isSoundEnabled then
   306     if isSoundEnabled then
   307 		InitSound();
   307         InitSound();
   308 
   308 
   309 	isDeveloperMode:= false;
   309     isDeveloperMode:= false;
   310 
   310 
   311 	TryDo(InitStepsFlags = cifAllInited, 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true);
   311     TryDo(InitStepsFlags = cifAllInited, 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true);
   312 
   312 
   313 	MainLoop();
   313     ParseCommand('rotmask', true);
   314 	OnDestroy();
   314 
   315 	exit();
   315     MainLoop();
       
   316     OnDestroy();
       
   317     exit();
   316 end;
   318 end;
   317 
   319 
   318 procedure initEverything;
   320 procedure initEverything;
   319 begin
   321 begin
   320 	init_uConsts();
   322     init_uConsts();
   321 	init_uMisc();
   323     init_uMisc();
   322 	init_uConsole();	// MUST happen after uMisc
   324     init_uConsole();	// MUST happen after uMisc
   323 	
   325     
   324 	init_uAI();
   326     init_uAI();
   325 	//uAIActions does not need initialization
   327     //uAIActions does not need initialization
   326 	//uAIAmmoTests does not need initialization
   328     //uAIAmmoTests does not need initialization
   327 	init_uAIMisc();
   329     init_uAIMisc();
   328 	init_uAmmos();
   330     init_uAmmos();
   329 	init_uChat();
   331     init_uChat();
   330 	init_uCollisions();
   332     init_uCollisions();
   331 	//uFloat does not need initialization
   333     //uFloat does not need initialization
   332 	//uGame does not need initialization
   334     //uGame does not need initialization
   333 	init_uGears();
   335     init_uGears();
   334 	init_uIO();
   336     init_uIO();
   335 	init_uKeys();
   337     init_uKeys();
   336 	init_uLand();
   338     init_uLand();
   337 	//uLandGraphics does not need initialization
   339     //uLandGraphics does not need initialization
   338 	//uLandObjects does not need initialization
   340     //uLandObjects does not need initialization
   339 	//uLandTemplates does not need initialization
   341     //uLandTemplates does not need initialization
   340 	//uLandTexture does not need initialization
   342     //uLandTexture does not need initialization
   341 	//uLocale does not need initialization
   343     //uLocale does not need initialization
   342 	init_uRandom();	
   344     init_uRandom();	
   343 	//uSHA does not need initialization
   345     //uSHA does not need initialization
   344 	init_uSound();
   346     init_uSound();
   345 	init_uStats();
   347     init_uStats();
   346 	init_uStore();
   348     init_uStore();
   347 	init_uTeams();
   349     init_uTeams();
   348 	init_uTriggers();
   350     init_uTriggers();
   349 	init_uVisualGears();
   351     init_uVisualGears();
   350 	init_uWorld();
   352     init_uWorld();
   351 	init_uScript();
   353     init_uScript();
   352 end;
   354 end;
   353 
   355 
   354 procedure freeEverything;
   356 procedure freeEverything;
   355 begin
   357 begin
   356 	free_uWorld();
   358     free_uWorld();
   357 	free_uVisualGears();	//stub
   359     free_uVisualGears();	//stub
   358 	free_uTriggers();	//stub
   360     free_uTriggers();	//stub
   359 	free_uTeams();
   361     free_uTeams();
   360 	free_uStore();
   362     free_uStore();
   361 	free_uStats();		//stub
   363     free_uStats();		//stub
   362 	free_uSound();		//stub
   364     free_uSound();		//stub
   363 	//uSHA does not need to be freed
   365     //uSHA does not need to be freed
   364 	free_uRandom();		//stub
   366     free_uRandom();		//stub
   365 	//uLocale does not need to be freed
   367     //uLocale does not need to be freed
   366 	//uLandTemplates does not need to be freed
   368     //uLandTemplates does not need to be freed
   367 	//uLandTexture does not need to be freed
   369     //uLandTexture does not need to be freed
   368 	//uLandObjects does not need to be freed
   370     //uLandObjects does not need to be freed
   369 	//uLandGraphics does not need to be freed
   371     //uLandGraphics does not need to be freed
   370 	free_uLand();
   372     free_uLand();
   371 	free_uKeys();		//stub
   373     free_uKeys();		//stub
   372 	free_uIO();
   374     free_uIO();
   373 	free_uGears();
   375     free_uGears();
   374 	//uGame does not need to be freed
   376     //uGame does not need to be freed
   375 	//uFloat does not need to be freed
   377     //uFloat does not need to be freed
   376 	free_uCollisions();
   378     free_uCollisions();
   377 	free_uChat();
   379     free_uChat();
   378 	free_uAmmos();
   380     free_uAmmos();
   379 	free_uAIMisc();		//stub
   381     free_uAIMisc();		//stub
   380 	//uAIAmmoTests does not need to be freed
   382     //uAIAmmoTests does not need to be freed
   381 	//uAIActions does not need to be freed
   383     //uAIActions does not need to be freed
   382 	free_uAI();		//stub
   384     free_uAI();		//stub
   383 
   385 
   384 	free_uConsole();
   386     free_uConsole();
   385 	free_uMisc();
   387     free_uMisc();
   386 	free_uConsts();		//stub
   388     free_uConsts();		//stub
   387 	free_uScript();
   389     free_uScript();
   388 end;
   390 end;
   389 
   391 
   390 {$IFNDEF HWLIBRARY}
   392 {$IFNDEF HWLIBRARY}
   391 /////////////////////////
   393 /////////////////////////
   392 procedure GenLandPreview;
   394 procedure GenLandPreview;
   393 var Preview: TPreview;
   395 var Preview: TPreview;
   394     h: byte;
   396     h: byte;
   395 begin
   397 begin
   396 	InitIPC;
   398     InitIPC;
   397 	IPCWaitPongEvent;
   399     IPCWaitPongEvent;
   398 	TryDo(InitStepsFlags = cifRandomize, 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true);
   400     TryDo(InitStepsFlags = cifRandomize, 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true);
   399 
   401 
   400 	Preview:= GenPreview;
   402     Preview:= GenPreview;
   401 	WriteLnToConsole('Sending preview...');
   403     WriteLnToConsole('Sending preview...');
   402 	SendIPCRaw(@Preview, sizeof(Preview));
   404     SendIPCRaw(@Preview, sizeof(Preview));
   403 	h:= MaxHedgehogs;
   405     h:= MaxHedgehogs;
   404 	SendIPCRaw(@h, sizeof(h));
   406     SendIPCRaw(@h, sizeof(h));
   405 	WriteLnToConsole('Preview sent, disconnect');
   407     WriteLnToConsole('Preview sent, disconnect');
   406 	CloseIPC();
   408     CloseIPC();
   407 end;
   409 end;
   408 
   410 
   409 ////////////////////////////////
   411 ////////////////////////////////
   410 procedure Resize(w, h: LongInt);
   412 procedure Resize(w, h: LongInt);
   411 begin
   413 begin
   412 	cScreenWidth:= w;
   414     cScreenWidth:= w;
   413 	cScreenHeight:= h;
   415     cScreenHeight:= h;
   414 	if cFullScreen then
   416     if cFullScreen then
   415 		ParseCommand('/fullscr 1', true)
   417         ParseCommand('/fullscr 1', true)
   416 	else
   418     else
   417 		ParseCommand('/fullscr 0', true);
   419         ParseCommand('/fullscr 0', true);
   418 end;
   420 end;
   419 
   421 
   420 /////////////////////
   422 /////////////////////
   421 procedure DisplayUsage;
   423 procedure DisplayUsage;
   422 var i: LongInt;
   424 var i: LongInt;
   423 begin
   425 begin
   424 	WriteLn('Wrong argument format: correct configurations is');
   426     WriteLn('Wrong argument format: correct configurations is');
   425 	WriteLn();
   427     WriteLn();
   426 	WriteLn('  hwengine <path to data folder> <path to replay file> [option]');
   428     WriteLn('  hwengine <path to data folder> <path to replay file> [option]');
   427 	WriteLn();
   429     WriteLn();
   428 	WriteLn('where [option] must be specified either as');
   430     WriteLn('where [option] must be specified either as');
   429 	WriteLn(' --set-video [screen width] [screen height] [color dept]');
   431     WriteLn(' --set-video [screen width] [screen height] [color dept]');
   430 	WriteLn(' --set-audio [volume] [enable music] [enable sounds]');
   432     WriteLn(' --set-audio [volume] [enable music] [enable sounds]');
   431 	WriteLn(' --set-other [language file] [full screen] [show FPS]');
   433     WriteLn(' --set-other [language file] [full screen] [show FPS]');
   432 	WriteLn(' --set-multimedia [screen height] [screen width] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen]');
   434     WriteLn(' --set-multimedia [screen height] [screen width] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen]');
   433 	WriteLn(' --set-everything [screen height] [screen width] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]');
   435     WriteLn(' --set-everything [screen height] [screen width] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]');
   434 	WriteLn();
   436     WriteLn();
   435 	WriteLn('Read documentation online at http://www.hedgewars.org/node/1465 for more information');
   437     WriteLn('Read documentation online at http://www.hedgewars.org/node/1465 for more information');
   436 	Write('parsed command: ');
   438     Write('parsed command: ');
   437 	for i:=0 to ParamCount do
   439     for i:=0 to ParamCount do
   438 		Write(ParamStr(i) + ' ');
   440         Write(ParamStr(i) + ' ');
   439 	WriteLn();
   441     WriteLn();
   440 end;
   442 end;
   441 
   443 
   442 ////////////////////
   444 ////////////////////
   443 procedure GetParams;
   445 procedure GetParams;
   444 {$IFDEF DEBUGFILE}
   446 {$IFDEF DEBUGFILE}
   445 var i: LongInt;
   447 var i: LongInt;
   446 {$ENDIF}
   448 {$ENDIF}
   447 begin
   449 begin
   448 
   450 
   449 	case ParamCount of
   451     case ParamCount of
   450 		18: begin
   452         18: begin
   451 			val(ParamStr(2), cScreenWidth);
   453             val(ParamStr(2), cScreenWidth);
   452 			val(ParamStr(3), cScreenHeight);
   454             val(ParamStr(3), cScreenHeight);
   453 			cInitWidth:= cScreenWidth;
   455             cInitWidth:= cScreenWidth;
   454 			cInitHeight:= cScreenHeight;
   456             cInitHeight:= cScreenHeight;
   455 			cBitsStr:= ParamStr(4);
   457             cBitsStr:= ParamStr(4);
   456 			val(cBitsStr, cBits);
   458             val(cBitsStr, cBits);
   457 			val(ParamStr(5), ipcPort);
   459             val(ParamStr(5), ipcPort);
   458 			cFullScreen:= ParamStr(6) = '1';
   460             cFullScreen:= ParamStr(6) = '1';
   459 			isSoundEnabled:= ParamStr(7) = '1';
   461             isSoundEnabled:= ParamStr(7) = '1';
   460 			cVSyncInUse:= ParamStr(8) = '1';
   462             cVSyncInUse:= ParamStr(8) = '1';
   461 			cWeaponTooltips:= ParamStr(9) = '1';
   463             cWeaponTooltips:= ParamStr(9) = '1';
   462 			cLocaleFName:= ParamStr(10);
   464             cLocaleFName:= ParamStr(10);
   463 			val(ParamStr(11), cInitVolume);
   465             val(ParamStr(11), cInitVolume);
   464 			val(ParamStr(12), cTimerInterval);
   466             val(ParamStr(12), cTimerInterval);
   465 			PathPrefix:= ParamStr(13);
   467             PathPrefix:= ParamStr(13);
   466 			cShowFPS:= ParamStr(14) = '1';
   468             cShowFPS:= ParamStr(14) = '1';
   467 			cAltDamage:= ParamStr(15) = '1';
   469             cAltDamage:= ParamStr(15) = '1';
   468 			UserNick:= DecodeBase64(ParamStr(16));
   470             UserNick:= DecodeBase64(ParamStr(16));
   469 			isMusicEnabled:= ParamStr(17) = '1';
   471             isMusicEnabled:= ParamStr(17) = '1';
   470 			cReducedQuality:= ParamStr(18) = '1';
   472             cReducedQuality:= ParamStr(18) = '1';
   471 		end;
   473         end;
   472 		3: begin
   474         3: begin
   473 			val(ParamStr(2), ipcPort);
   475             val(ParamStr(2), ipcPort);
   474 			GameType:= gmtLandPreview;
   476             GameType:= gmtLandPreview;
   475 			if ParamStr(3) <> 'landpreview' then 
   477             if ParamStr(3) <> 'landpreview' then 
   476 				OutError(errmsgShouldntRun, true);
   478                 OutError(errmsgShouldntRun, true);
   477 		end;
   479         end;
   478 		2: begin
   480         2: begin
   479 			PathPrefix:= ParamStr(1);
   481             PathPrefix:= ParamStr(1);
   480 			recordFileName:= ParamStr(2);
   482             recordFileName:= ParamStr(2);
   481 		end;
   483         end;
   482 		6: begin
   484         6: begin
   483 			PathPrefix:= ParamStr(1);
   485             PathPrefix:= ParamStr(1);
   484 			recordFileName:= ParamStr(2);
   486             recordFileName:= ParamStr(2);
   485 
   487 
   486 			if ParamStr(3) = '--set-video'	then
   488             if ParamStr(3) = '--set-video'	then
   487 			begin
   489             begin
   488 				val(ParamStr(4), cScreenWidth);
   490                 val(ParamStr(4), cScreenWidth);
   489 				val(ParamStr(5), cScreenHeight);
   491                 val(ParamStr(5), cScreenHeight);
   490 				cInitWidth:= cScreenWidth;
   492                 cInitWidth:= cScreenWidth;
   491 				cInitHeight:= cScreenHeight;
   493                 cInitHeight:= cScreenHeight;
   492 				cBitsStr:= ParamStr(6);
   494                 cBitsStr:= ParamStr(6);
   493 				val(cBitsStr, cBits);
   495                 val(cBitsStr, cBits);
   494 			end
   496             end
   495 			else
   497             else
   496 			begin
   498             begin
   497 				if ParamStr(3) = '--set-audio' then
   499                 if ParamStr(3) = '--set-audio' then
   498 				begin
   500                 begin
   499 					val(ParamStr(4), cInitVolume);
   501                     val(ParamStr(4), cInitVolume);
   500 					isMusicEnabled:= ParamStr(5) = '1';
   502                     isMusicEnabled:= ParamStr(5) = '1';
   501 					isSoundEnabled:= ParamStr(6) = '1';
   503                     isSoundEnabled:= ParamStr(6) = '1';
   502 				end
   504                 end
   503 				else
   505                 else
   504 				begin
   506                 begin
   505 					if ParamStr(3) = '--set-other' then
   507                     if ParamStr(3) = '--set-other' then
   506 					begin
   508                     begin
   507 						cLocaleFName:= ParamStr(4);
   509                         cLocaleFName:= ParamStr(4);
   508 						cFullScreen:= ParamStr(5) = '1';
   510                         cFullScreen:= ParamStr(5) = '1';
   509 						cShowFPS:= ParamStr(6) = '1';
   511                         cShowFPS:= ParamStr(6) = '1';
   510 					end
   512                     end
   511 					else GameType:= gmtSyntax;
   513                     else GameType:= gmtSyntax;
   512 				end
   514                 end
   513 			end;
   515             end;
   514 		end;
   516         end;
   515 		11: begin
   517         11: begin
   516 			PathPrefix:= ParamStr(1);
   518             PathPrefix:= ParamStr(1);
   517 			recordFileName:= ParamStr(2);
   519             recordFileName:= ParamStr(2);
   518 
   520 
   519 			if ParamStr(3) = '--set-multimedia' then
   521             if ParamStr(3) = '--set-multimedia' then
   520 			begin
   522             begin
   521 				val(ParamStr(4), cScreenWidth);
   523                 val(ParamStr(4), cScreenWidth);
   522 				val(ParamStr(5), cScreenHeight);
   524                 val(ParamStr(5), cScreenHeight);
   523 				cInitWidth:= cScreenWidth;
   525                 cInitWidth:= cScreenWidth;
   524 				cInitHeight:= cScreenHeight;
   526                 cInitHeight:= cScreenHeight;
   525 				cBitsStr:= ParamStr(6);
   527                 cBitsStr:= ParamStr(6);
   526 				val(cBitsStr, cBits);
   528                 val(cBitsStr, cBits);
   527 				val(ParamStr(7), cInitVolume);
   529                 val(ParamStr(7), cInitVolume);
   528 				isMusicEnabled:= ParamStr(8) = '1';
   530                 isMusicEnabled:= ParamStr(8) = '1';
   529 				isSoundEnabled:= ParamStr(9) = '1';
   531                 isSoundEnabled:= ParamStr(9) = '1';
   530 				cLocaleFName:= ParamStr(10);
   532                 cLocaleFName:= ParamStr(10);
   531 				cFullScreen:= ParamStr(11) = '1';
   533                 cFullScreen:= ParamStr(11) = '1';
   532 			end
   534             end
   533 			else GameType:= gmtSyntax;
   535             else GameType:= gmtSyntax;
   534 		end;
   536         end;
   535 		15: begin
   537         15: begin
   536 			PathPrefix:= ParamStr(1);
   538             PathPrefix:= ParamStr(1);
   537 			recordFileName:= ParamStr(2);
   539             recordFileName:= ParamStr(2);
   538 			if ParamStr(3) = '--set-everything' then
   540             if ParamStr(3) = '--set-everything' then
   539 			begin
   541             begin
   540 				val(ParamStr(4), cScreenWidth);
   542                 val(ParamStr(4), cScreenWidth);
   541 				val(ParamStr(5), cScreenHeight);
   543                 val(ParamStr(5), cScreenHeight);
   542 				cInitWidth:= cScreenWidth;
   544                 cInitWidth:= cScreenWidth;
   543 				cInitHeight:= cScreenHeight;
   545                 cInitHeight:= cScreenHeight;
   544 				cBitsStr:= ParamStr(6);
   546                 cBitsStr:= ParamStr(6);
   545 				val(cBitsStr, cBits);
   547                 val(cBitsStr, cBits);
   546 				val(ParamStr(7), cInitVolume);
   548                 val(ParamStr(7), cInitVolume);
   547 				isMusicEnabled:= ParamStr(8) = '1';
   549                 isMusicEnabled:= ParamStr(8) = '1';
   548 				isSoundEnabled:= ParamStr(9) = '1';
   550                 isSoundEnabled:= ParamStr(9) = '1';
   549 				cLocaleFName:= ParamStr(10);
   551                 cLocaleFName:= ParamStr(10);
   550 				cFullScreen:= ParamStr(11) = '1';
   552                 cFullScreen:= ParamStr(11) = '1';
   551 				cAltDamage:= ParamStr(12) = '1';
   553                 cAltDamage:= ParamStr(12) = '1';
   552 				cShowFPS:= ParamStr(13) = '1';
   554                 cShowFPS:= ParamStr(13) = '1';
   553 				val(ParamStr(14), cTimerInterval);
   555                 val(ParamStr(14), cTimerInterval);
   554 				cReducedQuality:= ParamStr(15) = '1';
   556                 cReducedQuality:= ParamStr(15) = '1';
   555 			end
   557             end
   556 			else GameType:= gmtSyntax;
   558             else GameType:= gmtSyntax;
   557 		end;
   559         end;
   558 		else GameType:= gmtSyntax;
   560         else GameType:= gmtSyntax;
   559 	end;
   561     end;
   560 
   562 
   561 {$IFDEF DEBUGFILE}
   563 {$IFDEF DEBUGFILE}
   562 	AddFileLog('Prefix: "' + PathPrefix +'"');
   564     AddFileLog('Prefix: "' + PathPrefix +'"');
   563 	for i:= 0 to ParamCount do
   565     for i:= 0 to ParamCount do
   564 		AddFileLog(inttostr(i) + ': ' + ParamStr(i));
   566         AddFileLog(inttostr(i) + ': ' + ParamStr(i));
   565 {$IFDEF IPHONEOS}
   567 {$IFDEF IPHONEOS}
   566 	WriteLnToConsole('Saving debug file at: ' + IPH_getDocumentsPath());
   568     WriteLnToConsole('Saving debug file at: ' + IPH_getDocumentsPath());
   567 {$ENDIF}
   569 {$ENDIF}
   568 {$ENDIF}
   570 {$ENDIF}
   569 end;
   571 end;
   570 ////////////////////////////////////////////////////////////////////////////////
   572 ////////////////////////////////////////////////////////////////////////////////
   571 /////////////////////////////// m a i n ////////////////////////////////////////
   573 /////////////////////////////// m a i n ////////////////////////////////////////
   572 ////////////////////////////////////////////////////////////////////////////////
   574 ////////////////////////////////////////////////////////////////////////////////
   573 
   575 
   574 begin
   576 begin
   575 	initEverything();
   577     initEverything();
   576 	WriteLnToConsole('Hedgewars ' + cVersionString + ' engine (network protocol: ' + inttostr(cNetProtoVersion) + ')');
   578     WriteLnToConsole('Hedgewars ' + cVersionString + ' engine (network protocol: ' + inttostr(cNetProtoVersion) + ')');
   577 	
   579     
   578 	GetParams();
   580     GetParams();
   579 	Randomize();
   581     Randomize();
   580 
   582 
   581 	if GameType = gmtLandPreview then GenLandPreview()
   583     if GameType = gmtLandPreview then GenLandPreview()
   582 	else if GameType = gmtSyntax then DisplayUsage()
   584     else if GameType = gmtSyntax then DisplayUsage()
   583 	else Game();
   585     else Game();
   584 	freeEverything();
   586     freeEverything();
   585 	
   587     
   586 	if GameType = gmtSyntax then
   588     if GameType = gmtSyntax then
   587 		ExitCode:= 1
   589         ExitCode:= 1
   588 	else
   590     else
   589 		ExitCode:= 0;
   591         ExitCode:= 0;
   590 {$ENDIF}
   592 {$ENDIF}
   591 end.
   593 end.