hedgewars/hwengine.pas
changeset 7110 c91d33837b0d
parent 7089 6c7210257945
child 7111 5ba5a92d74fb
child 7151 ec15d9e1a7e3
--- a/hedgewars/hwengine.pas	Thu May 03 22:48:02 2012 +0200
+++ b/hedgewars/hwengine.pas	Tue May 22 11:19:32 2012 +0200
@@ -31,7 +31,7 @@
 
 uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler, uSound,
      uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uRandom, uLandTexture, uCollisions,
-     sysutils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
+     SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
      {$IFDEF SDL13}, uTouch{$ENDIF}{$IFDEF ANDROID}, GLUnit{$ENDIF};
 
 {$IFDEF HWLIBRARY}
@@ -42,15 +42,15 @@
 
 implementation
 {$ELSE}
-procedure OnDestroy; forward;
 procedure initEverything(complete:boolean); forward;
 procedure freeEverything(complete:boolean); forward;
 {$ENDIF}
 
 ////////////////////////////////
-procedure DoTimer(Lag: LongInt);
+function DoTimer(Lag: LongInt): boolean;
 var s: shortstring;
 begin
+    DoTimer:= false;
     inc(RealTicks, Lag);
 
     case GameState of
@@ -71,12 +71,8 @@
             StoreLoad(false);
             InitWorld;
             ResetKbd;
-            SoundLoad;
             if GameType = gmtSave then
-                begin
-                isSEBackup:= isSoundEnabled;
-                isSoundEnabled:= false
-                end;
+                SetSound(false);
             FinishProgress;
             PlayMusic;
             SetScale(zoom);
@@ -86,7 +82,6 @@
         gsConfirm, gsGame:
             begin
             DrawWorld(Lag); // never place between ProcessKbd and DoGameTick - bugs due to /put cmd and isCursorVisible
-//            ProcessKbd;
             DoGameTick(Lag);
             ProcessVisualGears(Lag);
             end;
@@ -98,17 +93,13 @@
             end;
         gsExit:
             begin
-            isTerminated:= true;
+            DoTimer:= true;
             end;
         gsSuspend:
-            exit;
+            exit(false);
             end;
 
-{$IFDEF SDL13}
-    SDL_GL_SwapWindow(SDLwindow);
-{$ELSE}
-    SDL_GL_SwapBuffers();
-{$ENDIF}
+    SwapBuffers;
 
     if flagMakeCapture then
         begin
@@ -127,35 +118,18 @@
         end;
 end;
 
-////////////////////
-procedure OnDestroy;
-begin
-    WriteLnToConsole('Freeing resources...');
-    FreeActionsList();
-    StoreRelease(false);
-    ControllerClose();
-    CloseIPC();
-    TTF_Quit();
-{$IFDEF SDL13}
-    SDL_GL_DeleteContext(SDLGLcontext);
-    SDL_DestroyWindow(SDLwindow);
-    SDLGLcontext:= nil;
-    SDLwindow:= nil;
-{$ENDIF}
-    SDL_Quit();
-    isTerminated:= false;
-end;
-
 ///////////////////
 procedure MainLoop;
 var event: TSDL_Event;
     PrevTime, CurrTime: Longword;
+    isTerminated: boolean;
 {$IFDEF SDL13}
     previousGameState: TGameState;
 {$ELSE}
     prevFocusState: boolean;
 {$ENDIF}
 begin
+    isTerminated:= false;
     PrevTime:= SDL_GetTicks;
     while isTerminated = false do
     begin
@@ -166,40 +140,40 @@
             case event.type_ of
 {$IFDEF SDL13}
                 SDL_KEYDOWN:
-                if GameState = gsChat then
+                    if GameState = gsChat then
                     // sdl on iphone supports only ashii keyboards and the unicode field is deprecated in sdl 1.3
-                    KeyPressChat(SDL_GetKeyFromScancode(event.key.keysym.sym))//TODO correct for keymodifiers
-                else
-                    ProcessKey(event.key);
+                        KeyPressChat(SDL_GetKeyFromScancode(event.key.keysym.sym))//TODO correct for keymodifiers
+                    else
+                        ProcessKey(event.key);
                 SDL_KEYUP:
-                if GameState <> gsChat then
-                    ProcessKey(event.key);
+                    if GameState <> gsChat then
+                        ProcessKey(event.key);
                     
                 SDL_WINDOWEVENT:
                     if event.window.event = SDL_WINDOWEVENT_SHOWN then
-                        begin
+                    begin
                         cHasFocus:= true;
                         onFocusStateChanged()
-                        end
+                    end
                     else if event.window.event = SDL_WINDOWEVENT_MINIMIZED then
-                        begin
+                    begin
                         previousGameState:= GameState;
                         GameState:= gsSuspend;
-                        end
+                    end
                     else if event.window.event = SDL_WINDOWEVENT_RESTORED then
-                        begin
+                    begin
                         GameState:= previousGameState;
 {$IFDEF ANDROID}
                         //This call is used to reinitialize the glcontext and reload the textures
                         ParseCommand('fullscr '+intToStr(LongInt(cFullScreen)), true);
 {$ENDIF}
-                        end
+                    end
                     else if event.window.event = SDL_WINDOWEVENT_RESIZED then
-                        begin
+                    begin
                         cNewScreenWidth:= max(2 * (event.window.data1 div 2), cMinScreenWidth);
                         cNewScreenHeight:= max(2 * (event.window.data2 div 2), cMinScreenHeight);
                         cScreenResizeDelay:= RealTicks + 500{$IFDEF IPHONEOS}div 2{$ENDIF};
-                        end;
+                    end;
                         
                 SDL_FINGERMOTION:
                     onTouchMotion(event.tfinger.x, event.tfinger.y,event.tfinger.dx, event.tfinger.dy, event.tfinger.fingerId);
@@ -216,25 +190,26 @@
                     else
                         ProcessKey(event.key);
                 SDL_KEYUP:
-                if GameState <> gsChat then
-                    ProcessKey(event.key);
+                    if GameState <> gsChat then
+                        ProcessKey(event.key);
                     
                 SDL_MOUSEBUTTONDOWN:
-                    ProcessMouse(event.button, true); 
+                    ProcessMouse(event.button, true);
+                    
                 SDL_MOUSEBUTTONUP:
                     ProcessMouse(event.button, false); 
                     
                 SDL_ACTIVEEVENT:
                     if (event.active.state and SDL_APPINPUTFOCUS) <> 0 then
-                        begin
+                    begin
                         prevFocusState:= cHasFocus;
                         cHasFocus:= event.active.gain = 1;
                         if prevFocusState xor cHasFocus then
                             onFocusStateChanged()
-                        end;
+                    end;
                         
                 SDL_VIDEORESIZE:
-                    begin
+                begin
                     // using lower values than cMinScreenWidth or cMinScreenHeight causes widget overlap and off-screen widget parts
                     // Change by sheepluva:
                     // Let's only use even numbers for custom width/height since I ran into scaling issues with odd width values.
@@ -242,7 +217,7 @@
                     cNewScreenWidth:= max(2 * (event.resize.w div 2), cMinScreenWidth);
                     cNewScreenHeight:= max(2 * (event.resize.h div 2), cMinScreenHeight);
                     cScreenResizeDelay:= RealTicks+500;
-                    end;
+                end;
 {$ENDIF}
                 SDL_JOYAXISMOTION:
                     ControllerAxisEvent(event.jaxis.which, event.jaxis.axis, event.jaxis.value);
@@ -254,41 +229,37 @@
                     ControllerButtonEvent(event.jbutton.which, event.jbutton.button, false);
                 SDL_QUITEV:
                     isTerminated:= true
-        end; //end case event.type_ of
-    end; //end while SDL_PollEvent(@event) <> 0 do
-
-    if (cScreenResizeDelay <> 0) and (cScreenResizeDelay < RealTicks) and
-       ((cNewScreenWidth <> cScreenWidth) or (cNewScreenHeight <> cScreenHeight)) then
-    begin
-        cScreenResizeDelay:= 0;
-        cScreenWidth:= cNewScreenWidth;
-        cScreenHeight:= cNewScreenHeight;
+            end; //end case event.type_ of
+        end; //end while SDL_PollEvent(@event) <> 0 do
 
-        ParseCommand('fullscr '+intToStr(LongInt(cFullScreen)), true);
-        WriteLnToConsole('window resize: ' + IntToStr(cScreenWidth) + ' x ' + IntToStr(cScreenHeight));
-        ScriptOnScreenResize();
-        InitCameraBorders();
-        InitTouchInterface();
-    end;
+        if (cScreenResizeDelay <> 0) and (cScreenResizeDelay < RealTicks) and
+           ((cNewScreenWidth <> cScreenWidth) or (cNewScreenHeight <> cScreenHeight)) then
+        begin
+            cScreenResizeDelay:= 0;
+            cScreenWidth:= cNewScreenWidth;
+            cScreenHeight:= cNewScreenHeight;
 
-    if isTerminated = false then
-    begin
-        CurrTime:= SDL_GetTicks;
+            ParseCommand('fullscr '+intToStr(LongInt(cFullScreen)), true);
+            WriteLnToConsole('window resize: ' + IntToStr(cScreenWidth) + ' x ' + IntToStr(cScreenHeight));
+            ScriptOnScreenResize();
+            InitCameraBorders();
+            InitTouchInterface();
+        end;
+
+        CurrTime:= SDL_GetTicks();
         if PrevTime + longword(cTimerInterval) <= CurrTime then
         begin
-            DoTimer(CurrTime - PrevTime);
+            isTerminated:= DoTimer(CurrTime - PrevTime);
             PrevTime:= CurrTime
         end
         else SDL_Delay(1);
         IPCCheckSock();
-        end;
     end;
 end;
 
 ///////////////
 procedure Game{$IFDEF HWLIBRARY}(gameArgs: PPChar); cdecl; export{$ENDIF};
-var
-    p: TPathType;
+var p: TPathType;
     s: shortstring;
     i: LongInt;
 begin
@@ -310,8 +281,8 @@
         cLocale := Copy(cLocaleFName,1,2);
         
     UserNick:= gameArgs[5];
-    isSoundEnabled:= gameArgs[6] = '1';
-    isMusicEnabled:= gameArgs[7] = '1';
+    SetSound(gameArgs[6] = '1');
+    SetMusic(gameArgs[7] = '1');
     cAltDamage:= gameArgs[8] = '1';
     PathPrefix:= gameArgs[9];
     UserPathPrefix:= '../Documents';
@@ -382,61 +353,45 @@
     if recordFileName = '' then
         begin
         InitIPC;
-        SendIPCAndWaitReply('C');        // ask for game config
+        SendIPCAndWaitReply(_S'C');        // ask for game config
         end
     else
         LoadRecordFromFile(recordFileName);
 
     ScriptOnGameInit;
-
     s:= 'eproto ' + inttostr(cNetProtoVersion);
     SendIPCRaw(@s[0], Length(s) + 1); // send proto version
 
     InitTeams();
     AssignStores();
-
-    if isSoundEnabled then
-        InitSound();
+    InitSound();
 
     isDeveloperMode:= false;
-
     TryDo(InitStepsFlags = cifAllInited, 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true);
-
     ParseCommand('rotmask', true);
-
     MainLoop();
-    // clean up SDL and GL context
-    OnDestroy();
-    // clean up all the other memory allocated
+
+    // clean up all the memory allocated
     freeEverything(true);
-    if alsoShutdownFrontend then
-        halt;
 end;
 
 procedure initEverything (complete:boolean);
 begin
     Randomize();
 
-    if complete then
-        cLogfileBase:= 'game'
-    else
-        cLogfileBase:= 'preview';
-
-    // uConsts does not need initialization as they are all consts
-    uUtils.initModule;
+    uUtils.initModule(complete);      // this opens the debug file, must be the first
     uMisc.initModule;
     uVariables.initModule;
-    uConsole.initModule;    // MUST happen after uMisc
+    uConsole.initModule;
     uCommands.initModule;
     uCommandHandlers.initModule;
 
     uLand.initModule;
     uLandPainted.initModule;
-
     uIO.initModule;
 
     if complete then
-        begin
+    begin
 {$IFDEF ANDROID}GLUnit.init;{$ENDIF}
 {$IFDEF SDL13}uTouch.initModule;{$ENDIF}
         uAI.initModule;
@@ -464,18 +419,21 @@
         uVisualGears.initModule;
         uWorld.initModule;
         uCaptions.initModule;
-        end;
+    end;
 end;
 
 procedure freeEverything (complete:boolean);
 begin
     if complete then
-        begin
+    begin
+        WriteLnToConsole('Freeing resources...');
+        uAI.freeModule;
+        uAIMisc.freeModule;         //stub
         uCaptions.freeModule;
         uWorld.freeModule;
         uVisualGears.freeModule;
         uTeams.freeModule;
-        uStore.freeModule;          //stub
+        uInputHandler.freeModule;
         uStats.freeModule;          //stub
         uSound.freeModule;
         uScript.freeModule;
@@ -485,20 +443,18 @@
         uLandTexture.freeModule;
         //uLandObjects does not need to be freed
         //uLandGraphics does not need to be freed
-        uInputHandler.freeModule;           //stub
         uGears.freeModule;
         //uGame does not need to be freed
         //uFloat does not need to be freed
         uCollisions.freeModule;     //stub
         uChat.freeModule;
         uAmmos.freeModule;
-        uAIMisc.freeModule;         //stub
         //uAIAmmoTests does not need to be freed
         //uAIActions does not need to be freed
-        uAI.freeModule;             //stub
-        end;
+        uStore.freeModule;
+    end;
 
-    uIO.freeModule;             //stub
+    uIO.freeModule;
     uLand.freeModule;
     uLandPainted.freeModule;
 
@@ -512,8 +468,7 @@
 
 /////////////////////////
 procedure GenLandPreview{$IFDEF HWLIBRARY}(port: LongInt); cdecl; export{$ENDIF};
-var
-    Preview: TPreview;
+var Preview: TPreview;
 begin
     initEverything(false);
 {$IFDEF HWLIBRARY}
@@ -525,12 +480,11 @@
     IPCWaitPongEvent;
     TryDo(InitStepsFlags = cifRandomize, 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true);
 
-    Preview:= GenPreview();
+    GenPreview(Preview);
     WriteLnToConsole('Sending preview...');
     SendIPCRaw(@Preview, sizeof(Preview));
     SendIPCRaw(@MaxHedgehogs, sizeof(byte));
     WriteLnToConsole('Preview sent, disconnect');
-    CloseIPC();
     freeEverything(false);
 end;