Subversion Repositories plumbers

Rev

Rev 10 | Rev 12 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 10 Rev 11
Line 53... Line 53...
53
    numPics: Word;
53
    numPics: Word;
54
    unknown2: array[0..1] of Word;
54
    unknown2: array[0..1] of Word;
55
    scenes: array[0..99] of TSceneDef;        // Scenes start at 0x0016
55
    scenes: array[0..99] of TSceneDef;        // Scenes start at 0x0016
56
    pictures: array[0..1999] of TPictureDef;  // Pictures start at 0x2596
56
    pictures: array[0..1999] of TPictureDef;  // Pictures start at 0x2596
57
 
57
 
-
 
58
    class function MaxSceneCount: integer; static;
-
 
59
    class function MaxPictureCount: integer; static;
-
 
60
 
58
    function AddSceneAtEnd(SceneID: integer): PSceneDef;
61
    function AddSceneAtEnd(SceneID: integer): PSceneDef;
59
    procedure DeleteScene(SceneIndex: integer);
62
    procedure DeleteScene(SceneIndex: integer);
60
    procedure SwapScene(IndexA, IndexB: integer);
63
    procedure SwapScene(IndexA, IndexB: integer);
61
    procedure DeletePicture(PictureIndex: integer);
64
    procedure DeletePicture(PictureIndex: integer);
62
    procedure SwapPicture(IndexA, IndexB: integer);
65
    procedure SwapPicture(IndexA, IndexB: integer);
63
    function AddPictureBetween(Index: integer; assignToUpperScene: boolean=true): PPictureDef;
66
    function AddPictureBetween(Index: integer; assignToUpperScene: boolean=true): PPictureDef;
64
    function RealPictureCount: integer;
67
    function RealPictureCount: integer;
65
    function RealActionCount: integer;
68
    function RealActionCount: integer;
-
 
69
    function Defrag(OnlyCheck: boolean=false): boolean;
-
 
70
    function BiggestUsedPictureIndex: integer;
66
  end;
71
  end;
67
 
72
 
68
procedure _WriteStringToFilename(x: PAnsiFileName; s: AnsiString);
73
procedure _WriteStringToFilename(x: PAnsiFileName; s: AnsiString);
69
 
74
 
70
implementation
75
implementation
Line 76... Line 81...
76
begin
81
begin
77
  ZeroMemory(x, Length(x^));
82
  ZeroMemory(x, Length(x^));
78
  StrPLCopy(x^, s, Length(x^));
83
  StrPLCopy(x^, s, Length(x^));
79
end;
84
end;
80
 
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
 
81
function TGameBinFile.AddSceneAtEnd(SceneID: integer): PSceneDef;
98
function TGameBinFile.AddSceneAtEnd(SceneID: integer): PSceneDef;
82
begin
99
begin
83
  if Self.numScenes >= Length(Self.scenes) then raise Exception.Create('No more space for another scene');
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');
84
  if sceneID >= Length(Self.scenes) then raise Exception.Create('SceneID is too large.');
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*
85
  result := @Self.scenes[Self.numScenes];
103
  result := @Self.scenes[Self.numScenes];
86
  ZeroMemory(result, SizeOf(TSceneDef));
104
  ZeroMemory(result, SizeOf(TSceneDef));
87
  _WriteStringToFilename(@result.szSceneFolder, AnsiString(Format('SC%.2d', [sceneID])));
105
  _WriteStringToFilename(@result.szSceneFolder, AnsiString(Format('SC%.2d', [sceneID])));
88
  Inc(Self.numScenes);
106
  Inc(Self.numScenes);
89
end;
107
end;
Line 97... Line 115...
97
  end;
115
  end;
98
  ZeroMemory(@Self.scenes[Length(Self.scenes)-1], SizeOf(TSceneDef));
116
  ZeroMemory(@Self.scenes[Length(Self.scenes)-1], SizeOf(TSceneDef));
99
  Dec(Self.numScenes);
117
  Dec(Self.numScenes);
100
end;
118
end;
101
 
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
 
102
function TGameBinFile.RealActionCount: integer;
136
function TGameBinFile.RealActionCount: integer;
103
var
137
var
104
  iScene: integer;
138
  iScene: integer;
105
begin
139
begin
106
  result := 0;
140
  result := 0;
Line 130... Line 164...
130
  CopyMemory(@bakScene, @Self.scenes[IndexA], SizeOf(TSceneDef));
164
  CopyMemory(@bakScene, @Self.scenes[IndexA], SizeOf(TSceneDef));
131
  CopyMemory(@Self.scenes[IndexA], @Self.scenes[IndexB], SizeOf(TSceneDef));
165
  CopyMemory(@Self.scenes[IndexA], @Self.scenes[IndexB], SizeOf(TSceneDef));
132
  CopyMemory(@Self.scenes[IndexB], @bakScene, SizeOf(TSceneDef));
166
  CopyMemory(@Self.scenes[IndexB], @bakScene, SizeOf(TSceneDef));
133
end;
167
end;
134
 
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
 
135
procedure TGameBinFile.DeletePicture(PictureIndex: integer);
208
procedure TGameBinFile.DeletePicture(PictureIndex: integer);
136
var
209
var
137
  iScene, iScene2: integer;
210
  iScene, iScene2: integer;
138
  protection: integer; // prevents that two scenes get the same picture index when all pictures in a scene are deleted
211
  protection: integer; // prevents that two scenes get the same picture index when all pictures in a scene are deleted
139
begin
212
begin
Line 162... Line 235...
162
    begin
235
    begin
163
      Dec(Self.scenes[iScene].pictureIndex);
236
      Dec(Self.scenes[iScene].pictureIndex);
164
    end;
237
    end;
165
  end;
238
  end;
166
 
239
 
167
  If (PictureIndex+protection < Length(Self.pictures)-1) and (protection = 0) then
240
  If (PictureIndex < Length(Self.pictures)-1) and (protection = 0) then
168
  begin
241
  begin
169
    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));
170
  end;
-
 
171
  ZeroMemory(@Self.pictures[Length(Self.pictures)-1], SizeOf(TPictureDef));
243
    ZeroMemory(@Self.pictures[Length(Self.pictures)-1], SizeOf(TPictureDef));
-
 
244
  end;
172
 
245
 
173
  Dec(Self.numPics);
246
  Dec(Self.numPics);
174
end;
247
end;
175
 
248
 
176
procedure TGameBinFile.SwapPicture(IndexA, IndexB: integer);
249
procedure TGameBinFile.SwapPicture(IndexA, IndexB: integer);
Line 205... Line 278...
205
  end;
278
  end;
206
 
279
 
207
var
280
var
208
  iScene: integer;
281
  iScene: integer;
209
begin
282
begin
210
  if Self.numPics >= Length(Self.pictures) then raise Exception.Create('No more space for another picture');
-
 
211
  if ((Index < 0) or (Index >= Length(Self.pictures))) then raise Exception.Create('Invalid picture index');
283
  if ((Index < 0) or (Index >= Length(Self.pictures))) then raise Exception.Create('Invalid picture index');
212
 
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
 
213
  if assignToUpperScene then
291
  if assignToUpperScene then
214
  begin
292
  begin
215
    // Sc1   Sc2       Sc1   Sc2
293
    // Sc1   Sc2       Sc1   Sc2
216
    // A B | C    ==>  A B | X C
294
    // A B | C    ==>  A B | X C
217
    //       ^
295
    //       ^