Rev 10 | Rev 12 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 10 | Rev 11 | ||
---|---|---|---|
1 | unit GameBinStruct; |
1 | unit GameBinStruct; |
2 | 2 | ||
3 | {$A-} |
3 | {$A-} |
4 | 4 | ||
5 | interface |
5 | interface |
6 | 6 | ||
7 | const |
7 | const |
8 | SCENEID_PREVDECISION = -1; |
8 | SCENEID_PREVDECISION = -1; |
9 | SCENEID_ENDGAME = 32767; |
9 | SCENEID_ENDGAME = 32767; |
10 | 10 | ||
11 | type |
11 | type |
12 | PCoord = ^TCoord; |
12 | PCoord = ^TCoord; |
13 | TCoord = packed record |
13 | TCoord = packed record |
14 | x: Word; |
14 | x: Word; |
15 | y: Word; |
15 | y: Word; |
16 | end; |
16 | end; |
17 | 17 | ||
18 | PActionDef = ^TActionDef; |
18 | PActionDef = ^TActionDef; |
19 | TActionDef = packed record |
19 | TActionDef = packed record |
20 | scoreDelta: Integer; |
20 | scoreDelta: Integer; |
21 | nextSceneID: SmallInt; // will jump to the scene with the name "SC<nextSceneID>" |
21 | nextSceneID: SmallInt; // will jump to the scene with the name "SC<nextSceneID>" |
22 | // 7FFF (32767) = end game |
22 | // 7FFF (32767) = end game |
23 | // FFFF ( -1) = go back to the last decision |
23 | // FFFF ( -1) = go back to the last decision |
24 | sceneSegment: SmallInt; // 0 = scene from beginning, 1 = decision page |
24 | sceneSegment: SmallInt; // 0 = scene from beginning, 1 = decision page |
25 | cHotspotTopLeft: TCoord; |
25 | cHotspotTopLeft: TCoord; |
26 | cHotspotBottomRight: TCoord; |
26 | cHotspotBottomRight: TCoord; |
27 | end; |
27 | end; |
28 | 28 | ||
29 | PAnsiFileName = ^TAnsiFileName; |
29 | PAnsiFileName = ^TAnsiFileName; |
30 | TAnsiFileName = array[0..13] of AnsiChar; |
30 | TAnsiFileName = array[0..13] of AnsiChar; |
31 | 31 | ||
32 | PSceneDef = ^TSceneDef; |
32 | PSceneDef = ^TSceneDef; |
33 | TSceneDef = packed record |
33 | TSceneDef = packed record |
34 | numPics: Word; |
34 | numPics: Word; |
35 | pictureIndex: Word; |
35 | pictureIndex: Word; |
36 | numActions: Word; |
36 | numActions: Word; |
37 | szSceneFolder: TAnsiFileName; // Foldername *must* be "SCxx" (case sensitive) where xx stands for a 2 digit ID |
37 | szSceneFolder: TAnsiFileName; // Foldername *must* be "SCxx" (case sensitive) where xx stands for a 2 digit ID |
38 | szDialogWav: TAnsiFileName; |
38 | szDialogWav: TAnsiFileName; |
39 | szDecisionBmp: TAnsiFileName; |
39 | szDecisionBmp: TAnsiFileName; |
40 | actions: array[0..2] of TActionDef; |
40 | actions: array[0..2] of TActionDef; |
41 | end; |
41 | end; |
42 | 42 | ||
43 | PPictureDef = ^TPictureDef; |
43 | PPictureDef = ^TPictureDef; |
44 | TPictureDef = packed record |
44 | TPictureDef = packed record |
45 | duration: Word; // deciseconds |
45 | duration: Word; // deciseconds |
46 | szBitmapFile: TAnsiFileName; |
46 | szBitmapFile: TAnsiFileName; |
47 | end; |
47 | end; |
48 | 48 | ||
49 | PGameBinFile = ^TGameBinFile; |
49 | PGameBinFile = ^TGameBinFile; |
50 | TGameBinFile = packed record |
50 | TGameBinFile = packed record |
51 | unknown1: array[0..6] of Word; |
51 | unknown1: array[0..6] of Word; |
52 | numScenes: Word; |
52 | numScenes: Word; |
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 |
71 | 76 | ||
72 | uses |
77 | uses |
73 | Windows, SysUtils, Math; |
78 | Windows, SysUtils, Math; |
74 | 79 | ||
75 | procedure _WriteStringToFilename(x: PAnsiFileName; s: AnsiString); |
80 | procedure _WriteStringToFilename(x: PAnsiFileName; s: AnsiString); |
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; |
90 | 108 | ||
91 | procedure TGameBinFile.DeleteScene(SceneIndex: integer); |
109 | procedure TGameBinFile.DeleteScene(SceneIndex: integer); |
92 | begin |
110 | begin |
93 | if ((SceneIndex < 0) or (SceneIndex >= Length(Self.scenes))) then raise Exception.Create('Invalid scene index'); |
111 | if ((SceneIndex < 0) or (SceneIndex >= Length(Self.scenes))) then raise Exception.Create('Invalid scene index'); |
94 | If SceneIndex < Length(Self.scenes)-1 then |
112 | If SceneIndex < Length(Self.scenes)-1 then |
95 | begin |
113 | begin |
96 | CopyMemory(@Self.scenes[SceneIndex], @Self.scenes[SceneIndex+1], (Length(Self.scenes)-SceneIndex-1)*SizeOf(TSceneDef)); |
114 | CopyMemory(@Self.scenes[SceneIndex], @Self.scenes[SceneIndex+1], (Length(Self.scenes)-SceneIndex-1)*SizeOf(TSceneDef)); |
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; |
107 | for iScene := 0 to Self.numScenes - 1 do |
141 | for iScene := 0 to Self.numScenes - 1 do |
108 | begin |
142 | begin |
109 | result := result + Self.scenes[iScene].numActions; |
143 | result := result + Self.scenes[iScene].numActions; |
110 | end; |
144 | end; |
111 | end; |
145 | end; |
112 | 146 | ||
113 | function TGameBinFile.RealPictureCount: integer; |
147 | function TGameBinFile.RealPictureCount: integer; |
114 | var |
148 | var |
115 | iScene: integer; |
149 | iScene: integer; |
116 | begin |
150 | begin |
117 | result := 0; |
151 | result := 0; |
118 | for iScene := 0 to Self.numScenes - 1 do |
152 | for iScene := 0 to Self.numScenes - 1 do |
119 | begin |
153 | begin |
120 | result := result + Self.scenes[iScene].numPics; |
154 | result := result + Self.scenes[iScene].numPics; |
121 | end; |
155 | end; |
122 | end; |
156 | end; |
123 | 157 | ||
124 | procedure TGameBinFile.SwapScene(IndexA, IndexB: integer); |
158 | procedure TGameBinFile.SwapScene(IndexA, IndexB: integer); |
125 | var |
159 | var |
126 | bakScene: TSceneDef; |
160 | bakScene: TSceneDef; |
127 | begin |
161 | begin |
128 | if IndexA = IndexB then exit; |
162 | if IndexA = IndexB then exit; |
129 | if ((Min(IndexA, IndexB) < 0) or (Max(IndexA, IndexB) >= Length(Self.scenes))) then raise Exception.Create('Invalid scene index'); |
163 | if ((Min(IndexA, IndexB) < 0) or (Max(IndexA, IndexB) >= Length(Self.scenes))) then raise Exception.Create('Invalid scene index'); |
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 |
140 | if (PictureIndex < 0) or (PictureIndex >= Length(Self.pictures)) then raise Exception.Create('Invalid picture index'); |
213 | if (PictureIndex < 0) or (PictureIndex >= Length(Self.pictures)) then raise Exception.Create('Invalid picture index'); |
141 | 214 | ||
142 | protection := 0; |
215 | protection := 0; |
143 | for iScene := 0 to Self.numScenes-1 do |
216 | for iScene := 0 to Self.numScenes-1 do |
144 | begin |
217 | begin |
145 | if (PictureIndex >= Self.scenes[iScene].pictureIndex) and |
218 | if (PictureIndex >= Self.scenes[iScene].pictureIndex) and |
146 | (PictureIndex <= Self.scenes[iScene].pictureIndex + Self.scenes[iScene].numPics - 1) then |
219 | (PictureIndex <= Self.scenes[iScene].pictureIndex + Self.scenes[iScene].numPics - 1) then |
147 | begin |
220 | begin |
148 | Dec(Self.scenes[iScene].numPics); |
221 | Dec(Self.scenes[iScene].numPics); |
149 | if Self.scenes[iScene].numPics = 0 then |
222 | if Self.scenes[iScene].numPics = 0 then |
150 | begin |
223 | begin |
151 | for iScene2 := 0 to Self.numScenes-1 do |
224 | for iScene2 := 0 to Self.numScenes-1 do |
152 | begin |
225 | begin |
153 | if Self.scenes[iScene2].pictureIndex = PictureIndex+1 then |
226 | if Self.scenes[iScene2].pictureIndex = PictureIndex+1 then |
154 | begin |
227 | begin |
155 | protection := 1; |
228 | protection := 1; |
156 | break; |
229 | break; |
157 | end; |
230 | end; |
158 | end; |
231 | end; |
159 | end; |
232 | end; |
160 | end |
233 | end |
161 | else if (PictureIndex+protection < Self.scenes[iScene].pictureIndex) then |
234 | else if (PictureIndex+protection < Self.scenes[iScene].pictureIndex) then |
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); |
177 | var |
250 | var |
178 | bakPicture: TPictureDef; |
251 | bakPicture: TPictureDef; |
179 | begin |
252 | begin |
180 | // QUE: should we forbid that a picture between "scene borders" are swapped? |
253 | // QUE: should we forbid that a picture between "scene borders" are swapped? |
181 | 254 | ||
182 | if IndexA = IndexB then exit; |
255 | if IndexA = IndexB then exit; |
183 | if ((Min(IndexA, IndexB) < 0) or (Max(IndexA, IndexB) >= Length(Self.pictures))) then raise Exception.Create('Invalid picture index'); |
256 | if ((Min(IndexA, IndexB) < 0) or (Max(IndexA, IndexB) >= Length(Self.pictures))) then raise Exception.Create('Invalid picture index'); |
184 | 257 | ||
185 | CopyMemory(@bakPicture, @Self.pictures[IndexA], SizeOf(TPictureDef)); |
258 | CopyMemory(@bakPicture, @Self.pictures[IndexA], SizeOf(TPictureDef)); |
186 | CopyMemory(@Self.pictures[IndexA], @Self.pictures[IndexB], SizeOf(TPictureDef)); |
259 | CopyMemory(@Self.pictures[IndexA], @Self.pictures[IndexB], SizeOf(TPictureDef)); |
187 | CopyMemory(@Self.pictures[IndexB], @bakPicture, SizeOf(TPictureDef)); |
260 | CopyMemory(@Self.pictures[IndexB], @bakPicture, SizeOf(TPictureDef)); |
188 | end; |
261 | end; |
189 | 262 | ||
190 | function TGameBinFile.AddPictureBetween(Index: integer; assignToUpperScene: boolean=true): PPictureDef; |
263 | function TGameBinFile.AddPictureBetween(Index: integer; assignToUpperScene: boolean=true): PPictureDef; |
191 | 264 | ||
192 | function _HasBuffer(Index: integer): boolean; |
265 | function _HasBuffer(Index: integer): boolean; |
193 | var |
266 | var |
194 | iScene: integer; |
267 | iScene: integer; |
195 | begin |
268 | begin |
196 | for iScene := 0 to Self.numScenes-1 do |
269 | for iScene := 0 to Self.numScenes-1 do |
197 | begin |
270 | begin |
198 | if Self.scenes[iScene].pictureIndex = Index+1 then |
271 | if Self.scenes[iScene].pictureIndex = Index+1 then |
199 | begin |
272 | begin |
200 | result := true; |
273 | result := true; |
201 | exit; |
274 | exit; |
202 | end; |
275 | end; |
203 | end; |
276 | end; |
204 | result := false; |
277 | result := false; |
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 | // ^ |
218 | for iScene := 0 to Self.numScenes-1 do |
296 | for iScene := 0 to Self.numScenes-1 do |
219 | begin |
297 | begin |
220 | if (Index >= Self.scenes[iScene].pictureIndex) and |
298 | if (Index >= Self.scenes[iScene].pictureIndex) and |
221 | (index <= Self.scenes[iScene].pictureIndex + Max(0,Self.scenes[iScene].numPics - 1)) then |
299 | (index <= Self.scenes[iScene].pictureIndex + Max(0,Self.scenes[iScene].numPics - 1)) then |
222 | begin |
300 | begin |
223 | Inc(Self.scenes[iScene].numPics); |
301 | Inc(Self.scenes[iScene].numPics); |
224 | end |
302 | end |
225 | else if (index < Self.scenes[iScene].pictureIndex) and not _HasBuffer(index) then |
303 | else if (index < Self.scenes[iScene].pictureIndex) and not _HasBuffer(index) then |
226 | begin |
304 | begin |
227 | Inc(Self.scenes[iScene].pictureIndex); |
305 | Inc(Self.scenes[iScene].pictureIndex); |
228 | end; |
306 | end; |
229 | end; |
307 | end; |
230 | end |
308 | end |
231 | else |
309 | else |
232 | begin |
310 | begin |
233 | // Sc1 Sc2 Sc1 Sc2 |
311 | // Sc1 Sc2 Sc1 Sc2 |
234 | // A B | C ==> A B X | C |
312 | // A B | C ==> A B X | C |
235 | // ^ |
313 | // ^ |
236 | for iScene := 0 to Self.numScenes-1 do |
314 | for iScene := 0 to Self.numScenes-1 do |
237 | begin |
315 | begin |
238 | if (Index >= 1 + Self.scenes[iScene].pictureIndex) and |
316 | if (Index >= 1 + Self.scenes[iScene].pictureIndex) and |
239 | (index <= 1 + Self.scenes[iScene].pictureIndex + Max(0,Self.scenes[iScene].numPics-1)) then |
317 | (index <= 1 + Self.scenes[iScene].pictureIndex + Max(0,Self.scenes[iScene].numPics-1)) then |
240 | begin |
318 | begin |
241 | Inc(Self.scenes[iScene].numPics); |
319 | Inc(Self.scenes[iScene].numPics); |
242 | end |
320 | end |
243 | else if (index <= Self.scenes[iScene].pictureIndex) and not _HasBuffer(index) then |
321 | else if (index <= Self.scenes[iScene].pictureIndex) and not _HasBuffer(index) then |
244 | begin |
322 | begin |
245 | Inc(Self.scenes[iScene].pictureIndex); |
323 | Inc(Self.scenes[iScene].pictureIndex); |
246 | end; |
324 | end; |
247 | end; |
325 | end; |
248 | end; |
326 | end; |
249 | 327 | ||
250 | result := @Self.pictures[Index]; |
328 | result := @Self.pictures[Index]; |
251 | if not _HasBuffer(index) then |
329 | if not _HasBuffer(index) then |
252 | begin |
330 | begin |
253 | CopyMemory(@Self.pictures[Index+1], result, (Length(Self.pictures)-Index-1)*SizeOf(TPictureDef)); |
331 | CopyMemory(@Self.pictures[Index+1], result, (Length(Self.pictures)-Index-1)*SizeOf(TPictureDef)); |
254 | end; |
332 | end; |
255 | 333 | ||
256 | ZeroMemory(result, SizeOf(TPictureDef)); |
334 | ZeroMemory(result, SizeOf(TPictureDef)); |
257 | 335 | ||
258 | Inc(Self.numPics); |
336 | Inc(Self.numPics); |
259 | end; |
337 | end; |
260 | 338 | ||
261 | end. |
339 | end. |
262 | 340 |