Subversion Repositories plumbers

Rev

Rev 2 | Rev 20 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit Game;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, Classes, Forms, GameBinStruct;
  7.  
  8. type
  9.   TPictureType = (ptDia, ptDecision);
  10.  
  11.   THotspotIndex = 0..2;
  12.  
  13.   TGame = class;
  14.   PHotspot = ^THotspot;
  15.   THotspot = record
  16.     game: TGame;
  17.     lpAction: PActionDef;
  18.     cHotspotTopLeft: TCoord;
  19.     cHotspotBottomRight: TCoord;
  20.   end;
  21.  
  22.   TShowPictureCallback = procedure(Game: TGame; AFilename: string; AType: TPictureType) of object;
  23.   TPlaySoundCallback = procedure(Game: TGame; AFilename: string) of object;
  24.   TSimpleCallback = procedure(Game: TGame) of object;
  25.   TWaitCallback = procedure(Game: TGame; AMilliseconds: integer) of object;
  26.   TSetHotspotCallback = procedure(Game: TGame; AIndex: THotspotIndex; AHotspot: THotspot) of object;
  27.   TClearHotspotsCallback = procedure(Game: TGame) of object;
  28.  
  29.   TGame = class(TObject)
  30.   private
  31.     FPictureShowCallback: TShowPictureCallback;
  32.     FAsyncSoundCallback: TPlaySoundCallback;
  33.     FExitCallback: TSimpleCallback;
  34.     FWaitCallback: TWaitCallback;
  35.     FSetHotspotCallback: TSetHotspotCallback;
  36.     FClearHotspotsCallback: TClearHotspotsCallback;
  37.     FDirectory: string;
  38.     FScore: integer;
  39.     CurDecisionScene, LastDecisionScene: PSceneDef;
  40.     procedure TryExit;
  41.     procedure PrevDecisionScene;
  42.   protected
  43.     GameData: TGameBinFile;
  44.     procedure Wait(AMilliseconds: integer);
  45.     procedure PlayScene(scene: PSceneDef; goToDecision: boolean);
  46.   public
  47.     procedure PerformAction(action: PActionDef);
  48.     property PictureShowCallback: TShowPictureCallback read FPictureShowCallback write FPictureShowCallback;
  49.     property AsyncSoundCallback: TPlaySoundCallback read FAsyncSoundCallback write FAsyncSoundCallback;
  50.     property ExitCallback: TSimpleCallback read FExitCallback write FExitCallback;
  51.     property WaitCallback: TWaitCallback read FWaitCallback write FWaitCallback;
  52.     property SetHotspotCallback: TSetHotspotCallback read FSetHotspotCallback write FSetHotspotCallback;
  53.     property ClearHotspotsCallback: TClearHotspotsCallback read FClearHotspotsCallback write FClearHotspotsCallback;
  54.     property Directory: string read FDirectory;
  55.     property Score: integer read FScore;
  56.     constructor Create(ADirectory: string);
  57.     procedure Run;
  58.   end;
  59.  
  60. implementation
  61.  
  62. { TGame }
  63.  
  64. constructor TGame.Create(ADirectory: string);
  65. var
  66.   fs: TFileStream;
  67.   gameBinFilename: string;
  68. begin
  69.   FDirectory := ADirectory;
  70.  
  71.   gameBinFilename := IncludeTrailingPathDelimiter(ADirectory) + 'GAME.BIN';
  72.   if not FileExists(gameBinFilename) then
  73.   begin
  74.     raise Exception.Create('Cannot find GAME.BIN');
  75.   end;
  76.  
  77.   fs := TFileStream.Create(gameBinFilename, fmOpenRead);
  78.   try
  79.     fs.ReadBuffer(GameData, SizeOf(GameData));
  80.   finally
  81.     FreeAndNil(fs);
  82.   end;
  83. end;
  84.  
  85. procedure TGame.TryExit;
  86. begin
  87.   if Assigned(ExitCallback) then ExitCallback(Self);
  88. end;
  89.  
  90. procedure TGame.PrevDecisionScene;
  91. begin
  92.   if Assigned(LastDecisionScene) then PlayScene(LastDecisionScene, true)
  93. end;
  94.  
  95. procedure TGame.PerformAction(action: PActionDef);
  96. var
  97.   nextScene: PSceneDef;
  98. begin
  99.   Inc(FScore, action^.scoreDelta);
  100.   if action^.nextSceneID = SCENEID_PREVDECISION then
  101.     PrevDecisionScene
  102.   else if action^.nextSceneID = SCENEID_ENDGAME then
  103.     TryExit
  104.   else
  105.   begin
  106.     nextScene := GameData.FindScene(action^.nextSceneID);
  107.     if Assigned(nextScene) then
  108.       PlayScene(nextScene, action^.sceneSegment=SEGMENT_DECISION)
  109.     (*
  110.     else
  111.       raise Exception.CreateFmt('Scene %d was not found in GAME.BIN', [action^.nextSceneID]);
  112.     *)
  113.   end;
  114. end;
  115.  
  116. procedure TGame.Wait(AMilliseconds: integer);
  117. begin
  118.   if Assigned(WaitCallback) then
  119.     WaitCallback(Self, AMilliseconds)
  120.   else
  121.     Sleep(AMilliseconds);
  122. end;
  123.  
  124. procedure TGame.PlayScene(scene: PSceneDef; goToDecision: boolean);
  125. var
  126.   i: integer;
  127.   hotspot: THotspot;
  128. begin
  129.   if Assigned(ClearHotspotsCallback) then
  130.   begin
  131.     ClearHotspotsCallback(Self);
  132.   end;
  133.   if not goToDecision then
  134.   begin
  135.     if Assigned(AsyncSoundCallback) then
  136.     begin
  137.       AsyncSoundCallback(Self, IncludeTrailingPathDelimiter(FDirectory) +
  138.         scene^.szSceneFolder + PathDelim + scene^.szDialogWav);
  139.     end;
  140.     for i := scene^.pictureIndex to scene^.pictureIndex + scene^.numPics - 1 do
  141.     begin
  142.       if Assigned(PictureShowCallback) then
  143.       begin
  144.         PictureShowCallback(Self, IncludeTrailingPathDelimiter(FDirectory) +
  145.           scene^.szSceneFolder + PathDelim + GameData.pictures[i].szBitmapFile, ptDia);
  146.       end;
  147.       Wait(GameData.pictures[i].duration * 100);
  148.       if Application.Terminated then Abort;
  149.     end;
  150.   end;
  151.   if scene^.szDecisionBmp <> '' then
  152.   begin
  153.     LastDecisionScene := CurDecisionScene;
  154.     CurDecisionScene := scene;
  155.     if Assigned(PictureShowCallback) then
  156.     begin
  157.       PictureShowCallback(Self, IncludeTrailingPathDelimiter(FDirectory) +
  158.         scene^.szSceneFolder + PathDelim + scene^.szDecisionBmp, ptDecision);
  159.     end;
  160.     if Assigned(SetHotspotCallback) then
  161.     begin
  162.       for i := 0 to scene^.numActions - 1 do
  163.       begin
  164.         hotspot.Game := Self;
  165.         hotspot.lpAction := @scene^.actions[i];
  166.         hotspot.cHotspotTopLeft.X := scene^.actions[i].cHotspotTopLeft.X;
  167.         hotspot.cHotspotTopLeft.Y := scene^.actions[i].cHotspotTopLeft.Y;
  168.         hotspot.cHotspotBottomRight.X := scene^.actions[i].cHotspotBottomRight.X;
  169.         hotspot.cHotspotBottomRight.Y := scene^.actions[i].cHotspotBottomRight.Y;        
  170.         SetHotspotCallback(Self, i, hotspot);
  171.       end;
  172.     end;
  173.   end
  174.   else
  175.   begin
  176.     if scene^.numActions > 0 then PerformAction(@scene^.actions[0]);
  177.   end;
  178. end;
  179.  
  180. procedure TGame.Run;
  181. begin
  182.   if GameData.numScenes = 0 then exit;
  183.   PlayScene(@GameData.Scenes[0], false);
  184. end;
  185.  
  186. end.
  187.