Login | ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/plumbers/trunk/FileFormat/Delphi/GameBinStruct.pas
Revision: 2
Committed: Sat Sep 30 22:27:18 2017 UTC (4 years, 10 months ago) by daniel-marschall
Content type: text/x-pascal
File size: 6038 byte(s)
Log Message:
Initial release

File Contents

# Content
1 unit GameBinStruct;
2
3 {$A-}
4
5 interface
6
7 const
8 SCENEID_PREVDECISION = -1;
9 SCENEID_ENDGAME = 32767;
10
11 type
12 PCoord = ^TCoord;
13 TCoord = packed record
14 x: Word;
15 y: Word;
16 end;
17
18 PActionDef = ^TActionDef;
19 TActionDef = packed record
20 scoreDelta: Integer;
21 nextSceneID: SmallInt; // will jump to the scene with the name "SC<nextSceneID>"
22 // 7FFF (32767) = end game
23 // FFFF ( -1) = go back to the last decision
24 sceneSegment: SmallInt; // 0 = scene from beginning, 1 = decision page
25 cHotspotTopLeft: TCoord;
26 cHotspotBottomRight: TCoord;
27 end;
28
29 PAnsiFileName = ^TAnsiFileName;
30 TAnsiFileName = array[0..13] of AnsiChar;
31
32 PSceneDef = ^TSceneDef;
33 TSceneDef = packed record
34 numPics: Word;
35 pictureIndex: Word;
36 numActions: Word;
37 szSceneFolder: TAnsiFileName; // Foldername *must* be "SCxx" (case sensitive) where xx stands for a 2 digit ID
38 szDialogWav: TAnsiFileName;
39 szDecisionBmp: TAnsiFileName;
40 actions: array[0..2] of TActionDef;
41 end;
42
43 PPictureDef = ^TPictureDef;
44 TPictureDef = packed record
45 duration: Word; // deciseconds
46 szBitmapFile: TAnsiFileName;
47 end;
48
49 PGameBinFile = ^TGameBinFile;
50 TGameBinFile = packed record
51 unknown1: array[0..6] of Word;
52 numScenes: Word;
53 numPics: Word;
54 unknown2: array[0..1] of Word;
55 scenes: array[0..99] of TSceneDef; // Scenes start at 0x0016
56 pictures: array[0..1999] of TPictureDef; // Pictures start at 0x2596
57 function AddSceneAtEnd(SceneID: integer): PSceneDef;
58 procedure DeleteScene(SceneIndex: integer);
59 procedure SwapScene(IndexA, IndexB: integer);
60 procedure DeletePicture(PictureIndex: integer);
61 procedure SwapPicture(IndexA, IndexB: integer);
62 function AddPictureBetween(Index: integer): PPictureDef;
63 end;
64
65 procedure _WriteStringToFilename(x: PAnsiFileName; s: AnsiString);
66
67 implementation
68
69 uses
70 Windows, SysUtils, Math;
71
72 procedure _WriteStringToFilename(x: PAnsiFileName; s: AnsiString);
73 begin
74 ZeroMemory(x, Length(x^));
75 StrPLCopy(x^, s, Length(x^));
76 end;
77
78 function TGameBinFile.AddSceneAtEnd(SceneID: integer): PSceneDef;
79 begin
80 if Self.numScenes >= Length(Self.scenes) then raise Exception.Create('No more space for another scene');
81 if sceneID >= Length(Self.scenes) then raise Exception.Create('SceneID is too large.');
82 result := @Self.scenes[Self.numScenes];
83 ZeroMemory(result, SizeOf(TSceneDef));
84 _WriteStringToFilename(@result.szSceneFolder, AnsiString(Format('SC%.2d', [sceneID])));
85 Inc(Self.numScenes);
86 end;
87
88 procedure TGameBinFile.DeleteScene(SceneIndex: integer);
89 begin
90 if ((SceneIndex < 0) or (SceneIndex >= Length(Self.scenes))) then raise Exception.Create('Invalid scene index');
91 If SceneIndex < Length(Self.scenes)-1 then
92 begin
93 CopyMemory(@Self.scenes[SceneIndex], @Self.scenes[SceneIndex+1], (Length(Self.scenes)-SceneIndex-1)*SizeOf(TSceneDef));
94 end;
95 ZeroMemory(@Self.scenes[Length(Self.scenes)-1], SizeOf(TSceneDef));
96 end;
97
98 procedure TGameBinFile.SwapScene(IndexA, IndexB: integer);
99 var
100 bakScene: TSceneDef;
101 begin
102 if IndexA = IndexB then exit;
103 if ((Min(IndexA, IndexB) < 0) or (Max(IndexA, IndexB) >= Length(Self.scenes))) then raise Exception.Create('Invalid scene index');
104 CopyMemory(@bakScene, @Self.scenes[IndexA], SizeOf(TSceneDef));
105 CopyMemory(@Self.scenes[IndexA], @Self.scenes[IndexB], SizeOf(TSceneDef));
106 CopyMemory(@Self.scenes[IndexB], @bakScene, SizeOf(TSceneDef));
107 end;
108
109 procedure TGameBinFile.DeletePicture(PictureIndex: integer);
110 var
111 iScene: integer;
112 begin
113 if (PictureIndex < 0) or (PictureIndex >= Length(Self.pictures)) then raise Exception.Create('Invalid picture index');
114
115 for iScene := 0 to Self.numScenes-1 do
116 begin
117 if (PictureIndex >= Self.scenes[iScene].pictureIndex) and
118 (PictureIndex <= Self.scenes[iScene].pictureIndex + Self.scenes[iScene].numPics - 1) then
119 begin
120 Dec(Self.scenes[iScene].numPics);
121 end
122 else if (PictureIndex < Self.scenes[iScene].pictureIndex) then
123 begin
124 Dec(Self.scenes[iScene].pictureIndex);
125 end;
126 end;
127
128 If PictureIndex < Length(Self.pictures)-1 then
129 begin
130 CopyMemory(@Self.pictures[PictureIndex], @Self.pictures[PictureIndex+1], (Length(Self.pictures)-PictureIndex-1)*SizeOf(TPictureDef));
131 end;
132 ZeroMemory(@Self.pictures[Length(Self.pictures)-1], SizeOf(TPictureDef));
133 end;
134
135 procedure TGameBinFile.SwapPicture(IndexA, IndexB: integer);
136 var
137 bakPicture: TPictureDef;
138 begin
139 // QUE: should we forbid that a picture between "scene borders" are swapped?
140
141 if IndexA = IndexB then exit;
142 if ((Min(IndexA, IndexB) < 0) or (Max(IndexA, IndexB) >= Length(Self.pictures))) then raise Exception.Create('Invalid picture index');
143
144 CopyMemory(@bakPicture, @Self.pictures[IndexA], SizeOf(TPictureDef));
145 CopyMemory(@Self.pictures[IndexA], @Self.pictures[IndexB], SizeOf(TPictureDef));
146 CopyMemory(@Self.pictures[IndexB], @bakPicture, SizeOf(TPictureDef));
147 end;
148
149 function TGameBinFile.AddPictureBetween(Index: integer): PPictureDef;
150 var
151 iScene: integer;
152 begin
153 if Self.numPics >= Length(Self.pictures) then raise Exception.Create('No more space for another picture');
154 if ((Index < 0) or (Index >= Length(Self.pictures))) then raise Exception.Create('Invalid picture index');
155
156 for iScene := 0 to Self.numScenes-1 do
157 begin
158 if (Index >= Self.scenes[iScene].pictureIndex) and
159 (index <= Self.scenes[iScene].pictureIndex + Max(0,Self.scenes[iScene].numPics - 1)) then
160 begin
161 Inc(Self.scenes[iScene].numPics);
162 end
163 else if (index < Self.scenes[iScene].pictureIndex) then
164 begin
165 Inc(Self.scenes[iScene].pictureIndex);
166 end;
167 end;
168
169 result := @Self.pictures[Index];
170 CopyMemory(@Self.pictures[Index+1], result, (Length(Self.pictures)-Index-1)*SizeOf(TPictureDef));
171 ZeroMemory(result, SizeOf(TPictureDef));
172 end;
173
174 end.