Login | ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/plumbers/trunk/FileFormat/Delphi/GameBinStruct.pas
(Generate patch)

Comparing trunk/FileFormat/Delphi/GameBinStruct.pas (file contents):
Revision 10 by daniel-marschall, Wed Oct 4 11:24:27 2017 UTC vs.
Revision 11 by daniel-marschall, Wed Oct 4 12:43:05 2017 UTC

# Line 55 | Line 55 | type
55      scenes: array[0..99] of TSceneDef;        // Scenes start at 0x0016
56      pictures: array[0..1999] of TPictureDef;  // Pictures start at 0x2596
57  
58 +    class function MaxSceneCount: integer; static;
59 +    class function MaxPictureCount: integer; static;
60 +
61      function AddSceneAtEnd(SceneID: integer): PSceneDef;
62      procedure DeleteScene(SceneIndex: integer);
63      procedure SwapScene(IndexA, IndexB: integer);
# Line 63 | Line 66 | type
66      function AddPictureBetween(Index: integer; assignToUpperScene: boolean=true): PPictureDef;
67      function RealPictureCount: integer;
68      function RealActionCount: integer;
69 +    function Defrag(OnlyCheck: boolean=false): boolean;
70 +    function BiggestUsedPictureIndex: integer;
71    end;
72  
73   procedure _WriteStringToFilename(x: PAnsiFileName; s: AnsiString);
# Line 78 | Line 83 | begin
83    StrPLCopy(x^, s, Length(x^));
84   end;
85  
86 + function TGameBinFile.BiggestUsedPictureIndex: integer;
87 + var
88 +  iScene, candidate: integer;
89 + begin
90 +  result := -1;
91 +  for iScene := 0 to Self.numScenes - 1 do
92 +  begin
93 +    candidate := Self.scenes[iScene].pictureIndex + Self.scenes[iScene].numPics - 1;
94 +    if candidate > result then result := candidate;
95 +  end;
96 + end;
97 +
98   function TGameBinFile.AddSceneAtEnd(SceneID: integer): PSceneDef;
99   begin
100 <  if Self.numScenes >= Length(Self.scenes) then raise Exception.Create('No more space for another scene');
101 <  if sceneID >= Length(Self.scenes) then raise Exception.Create('SceneID is too large.');
100 >  if Self.numScenes >= Length(Self.scenes) then raise Exception.Create('Not enough space for another scene');
101 >  if SceneID < 0 then raise Exception.Create('Invalid scene ID');
102 >  if sceneID >= Length(Self.scenes) then raise Exception.Create('SceneID is too large.'); // TODO: I think this is not correct. This is the scene *ID*
103    result := @Self.scenes[Self.numScenes];
104    ZeroMemory(result, SizeOf(TSceneDef));
105    _WriteStringToFilename(@result.szSceneFolder, AnsiString(Format('SC%.2d', [sceneID])));
# Line 99 | Line 117 | begin
117    Dec(Self.numScenes);
118   end;
119  
120 + class function TGameBinFile.MaxPictureCount: integer;
121 + var
122 +  dummy: TGameBinFile;
123 + begin
124 +  dummy.numScenes := 1; // avoid compiler give a warning
125 +  result := Length(dummy.pictures);
126 + end;
127 +
128 + class function TGameBinFile.MaxSceneCount: integer;
129 + var
130 +  dummy: TGameBinFile;
131 + begin
132 +  dummy.numScenes := 1; // avoid compiler give a warning
133 +  result := Length(dummy.scenes);
134 + end;
135 +
136   function TGameBinFile.RealActionCount: integer;
137   var
138    iScene: integer;
# Line 132 | Line 166 | begin
166    CopyMemory(@Self.scenes[IndexB], @bakScene, SizeOf(TSceneDef));
167   end;
168  
169 + function TGameBinFile.Defrag(OnlyCheck: boolean=false): boolean;
170 + var
171 +  iPicture, iScene, iScene2: integer;
172 +  isGap: boolean;
173 + begin
174 +  result := false;
175 +  for iPicture := MaxPictureCount - 1 downto 0 do
176 +  begin
177 +    isGap := true;
178 +    for iScene := 0 to Self.numScenes - 1 do
179 +    begin
180 +      if (iPicture >= Self.scenes[iScene].pictureIndex) and
181 +         (iPicture <= Self.scenes[iScene].pictureIndex + Self.scenes[iScene].numPics - 1) then
182 +      begin
183 +        isGap := false;
184 +        break;
185 +      end;
186 +    end;
187 +    if isGap then
188 +    begin
189 +      result := true;
190 +      if not OnlyCheck then
191 +      begin
192 +        {$REGION 'Close the gap'}
193 +        for iScene2 := 0 to Self.numScenes - 1 do
194 +        begin
195 +          if (iPicture < Self.scenes[iScene2].pictureIndex) then
196 +          begin
197 +            Dec(Self.scenes[iScene2].pictureIndex);
198 +          end;
199 +        end;
200 +        CopyMemory(@Self.pictures[iPicture], @Self.pictures[iPicture+1], (Length(Self.pictures)-iPicture-1)*SizeOf(TPictureDef));
201 +        ZeroMemory(@Self.pictures[Length(Self.pictures)-1], SizeOf(TPictureDef));
202 +        {$ENDREGION}
203 +      end;
204 +    end;
205 +  end;
206 + end;
207 +
208   procedure TGameBinFile.DeletePicture(PictureIndex: integer);
209   var
210    iScene, iScene2: integer;
# Line 164 | Line 237 | begin
237      end;
238    end;
239  
240 <  If (PictureIndex+protection < Length(Self.pictures)-1) and (protection = 0) then
240 >  If (PictureIndex < Length(Self.pictures)-1) and (protection = 0) then
241    begin
242 <    CopyMemory(@Self.pictures[PictureIndex+protection], @Self.pictures[PictureIndex+protection+1], (Length(Self.pictures)-PictureIndex+protection-1)*SizeOf(TPictureDef));
242 >    CopyMemory(@Self.pictures[PictureIndex], @Self.pictures[PictureIndex+1], (Length(Self.pictures)-PictureIndex-1)*SizeOf(TPictureDef));
243 >    ZeroMemory(@Self.pictures[Length(Self.pictures)-1], SizeOf(TPictureDef));
244    end;
171  ZeroMemory(@Self.pictures[Length(Self.pictures)-1], SizeOf(TPictureDef));
245  
246    Dec(Self.numPics);
247   end;
# Line 207 | Line 280 | function TGameBinFile.AddPictureBetween(
280   var
281    iScene: integer;
282   begin
210  if Self.numPics >= Length(Self.pictures) then raise Exception.Create('No more space for another picture');
283    if ((Index < 0) or (Index >= Length(Self.pictures))) then raise Exception.Create('Invalid picture index');
284  
285 +  if (BiggestUsedPictureIndex = MaxPictureCount-1) and Defrag(true) then
286 +    raise Exception.Create('Not enough space for another picture. Please defrag to fill the gaps first.');
287 +
288 +  if Self.numPics >= MaxPictureCount then
289 +    raise Exception.Create('Not enough space for another picture. Maximum limit reached.');
290 +
291    if assignToUpperScene then
292    begin
293      // Sc1   Sc2       Sc1   Sc2

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines