Subversion Repositories Games.Carmageddon

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
20 pmbaty 1
#include "v1dbfile.h"
2
 
3
#include "CORE/FW/brqsort.h"
4
#include "CORE/FW/datafile.h"
5
#include "CORE/FW/diag.h"
6
#include "CORE/FW/file.h"
7
#include "CORE/FW/genfile.h"
8
#include "CORE/FW/resource.h"
9
#include "CORE/FW/scratch.h"
10
#include "CORE/V1DB/actsupt.h"
11
#include "CORE/V1DB/chunkids.h"
12
#include "CORE/V1DB/dbsetup.h"
13
#include "CORE/V1DB/matsupt.h"
14
#include "CORE/V1DB/modsupt.h"
15
#include "CORE/V1DB/regsupt.h"
16
#include "CORE/V1DB/stackids.h"
17
#include "harness/trace.h"
18
#include <stddef.h>
19
#include <stdlib.h>
20
#include <string.h>
21
 
22
br_file_struct_member br_vertex_FM[3] = {
23
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, p.v[0]), "p.v[x]", NULL },
24
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, p.v[1]), "p.v[y]", NULL },
25
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, p.v[2]), "p.v[z]", NULL }
26
};
27
br_file_struct br_vertex_F = { "br_vertex", BR_ASIZE(br_vertex_FM), br_vertex_FM, sizeof(br_vertex) };
28
 
29
br_file_struct_member br_vertex_uv_FM[] = {
30
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, map.v[0]), "map.v[0]", NULL },
31
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, map.v[1]), "map.v[1]", NULL }
32
};
33
br_file_struct br_vertex_uv_F = { "br_vertex_uv", BR_ASIZE(br_vertex_uv_FM), br_vertex_uv_FM, sizeof(br_vertex) };
34
 
35
br_file_struct_member br_old_vertex_uv_FM[5] = {
36
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, p.v[0]), "p.v[X]", NULL },
37
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, p.v[1]), "p.v[Y]", NULL },
38
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, p.v[2]), "p.v[Z]", NULL },
39
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, map.v[0]), "map.v[0]", NULL },
40
    { DF_TYPE_BR_SCALAR, offsetof(br_vertex, map.v[1]), "map.v[1]", NULL },
41
};
42
br_file_struct br_old_vertex_uv_F = { "br_old_vertex_uv", BR_ASIZE(br_old_vertex_uv_FM), br_old_vertex_uv_FM, sizeof(br_vertex) };
43
 
44
br_file_struct_member br_face_FM[5] = {
45
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[0]), "vertices[0]", NULL },
46
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[1]), "vertices[1]", NULL },
47
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[2]), "vertices[2]", NULL },
48
    { DF_TYPE_BR_UINT_16, offsetof(br_face, smoothing), "smoothing", NULL },
49
    { DF_TYPE_BR_UINT_8, offsetof(br_face, flags), "flags", NULL }
50
};
51
br_file_struct br_face_F = { "br_face", BR_ASIZE(br_face_FM), br_face_FM, sizeof(br_face) };
52
 
53
br_file_struct_member br_old_face_1_FM[5] = {
54
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[0]), "vertices[0]", NULL },
55
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[1]), "vertices[1]", NULL },
56
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[2]), "vertices[2]", NULL },
57
    { DF_TYPE_BR_UINT_8, offsetof(br_face, smoothing), "smoothing", NULL },
58
    { DF_TYPE_BR_UINT_8, offsetof(br_face, flags), "flags", NULL },
59
};
60
br_file_struct br_old_face_1_F = { "br_old_face_1", BR_ASIZE(br_old_face_1_FM), br_old_face_1_FM, sizeof(br_face) };
61
 
62
br_file_struct_member br_old_face_FM[5] = {
63
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[0]), "vertices[0]", NULL },
64
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[1]), "vertices[1]", NULL },
65
    { DF_TYPE_BR_UINT_16, offsetof(br_face, vertices[2]), "vertices[2]", NULL },
66
    { DF_TYPE_BR_UINT_16, offsetof(br_face, material), "material", NULL },
67
    { DF_TYPE_BR_UINT_16, offsetof(br_face, smoothing), "smoothing", NULL }, // DF_TYPE_BR_UINT_32 in EXE
68
};
69
br_file_struct br_old_face_F = { "br_old_face", BR_ASIZE(br_old_face_FM), br_old_face_FM, sizeof(br_face) };
70
 
71
br_file_struct_member br_model_FM[2] = {
72
    { DF_TYPE_BR_UINT_16, offsetof(br_model, flags), "flags", NULL },
73
    { DF_TYPE_ASCIZ, offsetof(br_model, identifier), "identifier", NULL }
74
};
75
br_file_struct br_model_F = { "br_model", BR_ASIZE(br_model_FM), br_model_FM, sizeof(br_model) };
76
 
77
br_file_struct_member br_old_model_1_FM[1] = {
78
    { DF_TYPE_ASCIZ, offsetof(br_model, identifier), "identifier", NULL },
79
};
80
br_file_struct br_old_model_1_F = { "br_old_model_1", BR_ASIZE(br_old_model_1_FM), br_old_model_1_FM, sizeof(br_model) };
81
 
82
br_file_struct_member br_pivot_FM[3] = {
83
    { DF_TYPE_BR_SCALAR, offsetof(br_model, pivot.v[0]), "pivot.v[X]", NULL },
84
    { DF_TYPE_BR_SCALAR, offsetof(br_model, pivot.v[1]), "pivot.v[Y]", NULL },
85
    { DF_TYPE_BR_SCALAR, offsetof(br_model, pivot.v[2]), "pivot.v[Z]", NULL },
86
};
87
br_file_struct br_pivot_F = { "br_pivot", BR_ASIZE(br_pivot_FM), br_pivot_FM, sizeof(br_model) };
88
 
89
br_file_struct_member br_material_old_FM[13] = {
90
    { DF_TYPE_BR_COLOUR, offsetof(br_material, colour), "colour", NULL },
91
    { DF_TYPE_BR_UINT_8, offsetof(br_material, opacity), "opacity", NULL },
92
    { DF_TYPE_BR_UFRACTION, offsetof(br_material, ka), "ka", NULL },
93
    { DF_TYPE_BR_UFRACTION, offsetof(br_material, kd), "kd", NULL },
94
    { DF_TYPE_BR_UFRACTION, offsetof(br_material, ks), "ks", NULL },
95
    { DF_TYPE_BR_SCALAR, offsetof(br_material, power), "power", NULL },
96
    { DF_TYPE_BR_UINT_16, offsetof(br_material, flags), "flags", NULL },
97
    { DF_TYPE_BR_VECTOR2, offsetof(br_material, map_transform.m[0]), "map_transform.m[0]", NULL },
98
    { DF_TYPE_BR_VECTOR2, offsetof(br_material, map_transform.m[1]), "map_transform.m[1]", NULL },
99
    { DF_TYPE_BR_VECTOR2, offsetof(br_material, map_transform.m[2]), "map_transform.m[2]", NULL },
100
    { DF_TYPE_BR_UINT_8, offsetof(br_material, index_base), "index_base", NULL },
101
    { DF_TYPE_BR_UINT_8, offsetof(br_material, index_range), "index_range", NULL },
102
    { DF_TYPE_ASCIZ, offsetof(br_material, identifier), "identifier", NULL }
103
};
104
br_file_struct br_material_old_F = { "br_material_old", BR_ASIZE(br_material_old_FM), br_material_old_FM, sizeof(br_material) };
105
 
106
br_file_struct_member br_material_FM[17] = {
107
    { DF_TYPE_BR_COLOUR, offsetof(br_material, colour), "colour", NULL },
108
    { DF_TYPE_BR_UINT_8, offsetof(br_material, opacity), "opacity", NULL },
109
    { DF_TYPE_BR_UFRACTION, offsetof(br_material, ka), "ka", NULL },
110
    { DF_TYPE_BR_UFRACTION, offsetof(br_material, kd), "kd", NULL },
111
    { DF_TYPE_BR_UFRACTION, offsetof(br_material, ks), "ks", NULL },
112
    { DF_TYPE_BR_SCALAR, offsetof(br_material, power), "power", NULL },
113
    { DF_TYPE_BR_UINT_32, offsetof(br_material, flags), "flags", NULL },
114
    { DF_TYPE_BR_VECTOR2, offsetof(br_material, map_transform.m[0]), "map_transform.m[0]", NULL },
115
    { DF_TYPE_BR_VECTOR2, offsetof(br_material, map_transform.m[1]), "map_transform.m[1]", NULL },
116
    { DF_TYPE_BR_VECTOR2, offsetof(br_material, map_transform.m[2]), "map_transform.m[2]", NULL },
117
    { DF_TYPE_BR_UINT_8, offsetof(br_material, index_base), "index_base", NULL },
118
    { DF_TYPE_BR_UINT_8, offsetof(br_material, index_range), "index_range", NULL },
119
    { DF_TYPE_BR_SCALAR, offsetof(br_material, fog_min), "fog_min", NULL },
120
    { DF_TYPE_BR_SCALAR, offsetof(br_material, fog_max), "fog_max", NULL },
121
    { DF_TYPE_BR_COLOUR, offsetof(br_material, fog_colour), "fog_colour", NULL },
122
    { DF_TYPE_BR_INT_32, offsetof(br_material, subdivide_tolerance), "subdivide_tolerance", NULL },
123
    { DF_TYPE_ASCIZ, offsetof(br_material, identifier), "identifier", NULL },
124
};
125
br_file_struct br_material_F = { "br_material", BR_ASIZE(br_material_FM), br_material_FM, sizeof(br_material) };
126
 
127
struct {
128
    br_uint_32 id;
129
    size_t offset;
130
    int table;
131
} MaterialMaps[5] = {
132
    { CHUNKID_MATERIAL_COLOUR_MAP, offsetof(br_material, colour_map), 0 },
133
    { CHUNKID_MATERIAL_INDEX_BLEND, offsetof(br_material, index_blend), 1 },
134
    { CHUNKID_MATERIAL_INDEX_SHADE, offsetof(br_material, index_shade), 1 },
135
    { CHUNKID_MATERIAL_SCREENDOOR, offsetof(br_material, screendoor), 1 },
136
    { CHUNKID_MATERIAL_INDEX_FOG, offsetof(br_material, index_fog), 1 },
137
};
138
 
139
br_file_enum_member actor_type_FM[8] = {
140
    { 0, "BR_ACTOR_NONE" },
141
    { 1, "BR_ACTOR_MODEL" },
142
    { 2, "BR_ACTOR_LIGHT" },
143
    { 3, "BR_ACTOR_CAMERA" },
144
    { 4, "_BR_ACTOR_RESERVED" },
145
    { 5, "BR_ACTOR_BOUNDS" },
146
    { 6, "BR_ACTOR_BOUNDS_CORRECT" },
147
    { 7, "BR_ACTOR_CLIP_PLANE" }
148
};
149
br_file_enum actor_type_F = { BR_ASIZE(actor_type_FM), actor_type_FM };
150
 
151
br_file_enum_member render_style_FM[8] = {
152
    { 0, "BR_RSTYLE_DEFAULT"},
153
    { 1, "BR_RSTYLE_NONE"},
154
    { 2, "BR_RSTYLE_POINTS"},
155
    { 3, "BR_RSTYLE_EDGES"},
156
    { 4, "BR_RSTYLE_FACES"},
157
    { 5, "BR_RSTYLE_BOUNDING_POINTS"},
158
    { 6, "BR_RSTYLE_BOUNDING_EDGES"},
159
    { 7, "BR_RSTYLE_BOUNDING_FACES"},
160
};
161
br_file_enum render_style_F = { 8, render_style_FM };
162
 
163
br_file_struct_member br_actor_FM[3] = {
164
    { DF_TYPE_ENUM_8, offsetof(br_actor, type), "type", &actor_type_F },
165
    { DF_TYPE_ENUM_8, offsetof(br_actor, render_style), "render_style", &render_style_F },
166
    { DF_TYPE_ASCIZ, offsetof(br_actor, identifier), "identifier", NULL }
167
};
168
br_file_struct br_actor_F = { "br_actor", BR_ASIZE(br_actor_FM), br_actor_FM, sizeof(br_actor) };
169
 
170
br_file_struct_member br_transform_matrix34_FM[4] = {
171
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.mat.m[0]), "t.mat.m[0]", NULL },
172
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.mat.m[1]), "t.mat.m[1]", NULL },
173
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.mat.m[2]), "t.mat.m[2]", NULL },
174
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.mat.m[3]), "t.mat.m[3]", NULL }
175
};
176
br_file_struct br_transform_matrix34_F = { "br_transform_matrix34", BR_ASIZE(br_transform_matrix34_FM), br_transform_matrix34_FM, sizeof(br_transform) };
177
 
178
br_file_struct_member br_transform_quat_FM[5] = {
179
    { DF_TYPE_BR_SCALAR, offsetof(br_transform, t.quat.q.x), "t.quat.q.x", NULL },
180
    { DF_TYPE_BR_SCALAR, offsetof(br_transform, t.quat.q.y), "t.quat.q.y", NULL },
181
    { DF_TYPE_BR_SCALAR, offsetof(br_transform, t.quat.q.z), "t.quat.q.z", NULL },
182
    { DF_TYPE_BR_SCALAR, offsetof(br_transform, t.quat.q.w), "t.quat.q.w", NULL },
183
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.quat.t), "t.quat.t", NULL },
184
};
185
br_file_struct br_transform_quat_F = { "br_transform_quat", BR_ASIZE(br_transform_quat_FM), br_transform_quat_FM, sizeof(br_transform) };
186
 
187
br_file_enum_member angle_order_FM[24] = {
188
    { 0, "BR_EULER_XYZ_S" },
189
    { 8, "BR_EULER_XYX_S" },
190
    { 4, "BR_EULER_XZY_S" },
191
    { 12, "BR_EULER_XZX_S" },
192
    { 1, "BR_EULER_YZX_S" },
193
    { 9, "BR_EULER_YZY_S" },
194
    { 5, "BR_EULER_YXZ_S" },
195
    { 13, "BR_EULER_YXY_S" },
196
    { 2, "BR_EULER_ZXY_S" },
197
    { 10, "BR_EULER_ZXZ_S" },
198
    { 6, "BR_EULER_ZYX_S" },
199
    { 14, "BR_EULER_ZYZ_S" },
200
    { 16, "BR_EULER_ZYX_R" },
201
    { 24, "BR_EULER_XYX_R" },
202
    { 20, "BR_EULER_YZX_R" },
203
    { 28, "BR_EULER_XZX_R" },
204
    { 17, "BR_EULER_XZY_R" },
205
    { 25, "BR_EULER_YZY_R" },
206
    { 21, "BR_EULER_ZXY_R" },
207
    { 29, "BR_EULER_YXY_R" },
208
    { 18, "BR_EULER_YXZ_R" },
209
    { 26, "BR_EULER_ZXZ_R" },
210
    { 22, "BR_EULER_XYZ_R" },
211
    { 30, "BR_EULER_ZYZ_R" },
212
};
213
br_file_enum angle_order_F = { BR_ASIZE(angle_order_FM), angle_order_FM };
214
 
215
br_file_struct_member br_transform_euler_FM[5] = {
216
    { DF_TYPE_ENUM_8, offsetof(br_transform, t.euler.e.order), "t.euler.e.order", &angle_order_F },
217
    { DF_TYPE_BR_ANGLE, offsetof(br_transform, t.euler.e.a), "t.euler.e.a", NULL },
218
    { DF_TYPE_BR_ANGLE, offsetof(br_transform, t.euler.e.b), "t.euler.e.b", NULL },
219
    { DF_TYPE_BR_ANGLE, offsetof(br_transform, t.euler.e.c), "t.euler.e.c", NULL },
220
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.euler.t), "t.euler.t", NULL },
221
};
222
br_file_struct br_transform_euler_F = { "br_transform_euler", BR_ASIZE(br_transform_euler_FM), br_transform_euler_FM, sizeof(br_transform) };
223
 
224
br_file_struct_member br_transform_look_up_FM[3] = {
225
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.look_up.look), "t.look_up.look", NULL },
226
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.look_up.up), "t.look_up.up", NULL },
227
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.look_up.t), "t.look_up.t", NULL },
228
};
229
br_file_struct br_transform_look_up_F =  { "br_transform_look_up", BR_ASIZE(br_transform_look_up_FM), br_transform_look_up_FM, sizeof(br_transform) };
230
 
231
br_file_struct_member br_transform_translation_FM[1] = {
232
    { DF_TYPE_BR_VECTOR3, offsetof(br_transform, t.translate.t), "t.translate.t", NULL },
233
};
234
br_file_struct br_transform_translation_F = { "br_transform_translation", BR_ASIZE(br_transform_translation_FM), br_transform_translation_FM, sizeof(br_transform) };
235
 
236
transform_type TransformTypes[7] = {
237
    { CHUNKID_TRANSFORM_MAT34, &br_transform_matrix34_F },
238
    { CHUNKID_TRANSFORM_MAT34_LP, &br_transform_matrix34_F },
239
    { CHUNKID_TRANSFORM_QUAT, &br_transform_quat_F },
240
    { CHUNKID_TRANSFORM_EULER, &br_transform_euler_F },
241
    { CHUNKID_TRANSFORM_LOOK_UP, &br_transform_look_up_F },
242
    { CHUNKID_TRANSFORM_TRANSLATION, &br_transform_translation_F },
243
    { CHUNKID_TRANSFORM_IDENTITY, NULL }
244
};
245
 
246
br_file_struct_member br_bounds3_FM[2] = {
247
    { DF_TYPE_BR_VECTOR3, offsetof(br_bounds3, min), "min", NULL },
248
    { DF_TYPE_BR_VECTOR3, offsetof(br_bounds3, max), "max", NULL },
249
};
250
br_file_struct br_bounds3_F = { "br_bounds3", BR_ASIZE(br_bounds3_FM), br_bounds3_FM, sizeof(br_bounds3) };
251
 
252
br_file_struct_member br_plane_FM[1] = {
253
    { DF_TYPE_BR_VECTOR4, offsetof(br_vector4, v), "eqn", NULL },
254
};
255
br_file_struct br_plane_F = { "br_plane", BR_ASIZE(br_plane_FM), br_plane_FM, sizeof(br_vector4) };
256
 
257
br_file_enum_member light_type_FM[6] = {
258
    { 0, "BR_LIGHT_POINT"},
259
    { 1, "BR_LIGHT_DIRECT"},
260
    { 2, "BR_LIGHT_SPOT"},
261
    { 4, "BR_LIGHT_VIEW|BR_LIGHT_POINT"},
262
    { 5, "BR_LIGHT_VIEW|BR_LIGHT_DIRECT"},
263
    { 6, "BR_LIGHT_VIEW|BR_LIGHT_SPOT"},
264
};
265
br_file_enum light_type_F = { BR_ASIZE(light_type_FM), light_type_FM };
266
 
267
br_file_struct_member br_light_FM[8] = {
268
    { DF_TYPE_ENUM_8, offsetof(br_light, type), "type", &light_type_F },
269
    { DF_TYPE_BR_COLOUR, offsetof(br_light, colour), "colour", NULL },
270
    { DF_TYPE_BR_SCALAR, offsetof(br_light, attenuation_c), "attenuation_c", NULL },
271
    { DF_TYPE_BR_SCALAR, offsetof(br_light, attenuation_l), "attenuation_l", NULL },
272
    { DF_TYPE_BR_SCALAR, offsetof(br_light, attenuation_q), "attenuation_q", NULL },
273
    { DF_TYPE_BR_ANGLE, offsetof(br_light, cone_inner), "cone_inner", NULL },
274
    { DF_TYPE_BR_ANGLE, offsetof(br_light, cone_outer), "cone_outer", NULL },
275
    { DF_TYPE_ASCIZ, offsetof(br_light, identifier), "identifier", NULL },
276
};
277
br_file_struct br_light_F = { "br_light", BR_ASIZE(br_light_FM), br_light_FM, sizeof(br_light) };
278
 
279
br_file_enum_member camera_type_FM[2] = {
280
    { 0, "BR_CAMERA_PARALLEL"},
281
    { 1, "BR_CAMERA_PERSPECTIVE"},
282
};
283
br_file_enum camera_type_F = { BR_ASIZE(camera_type_FM), camera_type_FM };
284
 
285
br_file_struct_member br_camera_FM[6] = {
286
    { DF_TYPE_ENUM_8, offsetof(br_camera, type), "type", &camera_type_F },
287
    { DF_TYPE_BR_ANGLE, offsetof(br_camera, field_of_view), "field_of_view", NULL },
288
    { DF_TYPE_BR_SCALAR, offsetof(br_camera, hither_z), "hither_z", NULL },
289
    { DF_TYPE_BR_SCALAR, offsetof(br_camera, yon_z), "yon_z", NULL },
290
    { DF_TYPE_BR_SCALAR, offsetof(br_camera, aspect), "aspect", NULL },
291
    { DF_TYPE_ASCIZ, offsetof(br_camera, identifier), "identifier", NULL },
292
};
293
br_file_struct br_camera_F = { "br_camera", BR_ASIZE(br_camera_FM), br_camera_FM, sizeof(br_camera) };
294
 
295
br_chunks_table_entry ModelLoadEntries[15] = {
296
    { CHUNKID_END, 0u, FopRead_END },
297
    { CHUNKID_OLD_MATERIAL_INDEX, 0u, FopRead_OLD_MATERIAL_INDEX },
298
    { CHUNKID_OLD_VERTICES, 0u, FopRead_OLD_VERTICES },
299
    { CHUNKID_OLD_VERTICES_UV, 0u, FopRead_OLD_VERTICES_UV },
300
    { CHUNKID_OLD_FACES, 0u, FopRead_OLD_FACES },
301
    { CHUNKID_OLD_MODEL, 0u, FopRead_OLD_MODEL },
302
    { CHUNKID_OLD_FACES_1, 1u, FopRead_OLD_FACES_1 },
303
    { CHUNKID_OLD_MODEL_1, 0u, FopRead_OLD_MODEL_1 },
304
    { CHUNKID_MODEL, 0u, FopRead_MODEL },
305
    { CHUNKID_MATERIAL_INDEX, 1u, FopRead_MATERIAL_INDEX },
306
    { CHUNKID_MODEL_VERTICES, 1u, FopRead_VERTICES },
307
    { CHUNKID_MODEL_VERTEX_UV, 1u, FopRead_VERTEX_UV },
308
    { CHUNKID_MODEL_FACES, 1u, FopRead_FACES },
309
    { CHUNKID_MODEL_FACE_MATERIAL, 0u, FopRead_FACE_MATERIAL },
310
    { CHUNKID_MODEL_PIVOT, 0u, FopRead_PIVOT },
311
};
312
br_chunks_table ModelLoadTable = { BR_ASIZE(ModelLoadEntries), ModelLoadEntries };
313
 
314
br_chunks_table_entry ActorLoadEntries[21] = {
315
    { CHUNKID_END, 0u, FopRead_END },
316
    { CHUNKID_ACTOR, 0u, FopRead_ACTOR },
317
    { CHUNKID_ACTOR_MODEL, 0u, FopRead_ACTOR_MODEL },
318
    { CHUNKID_ACTOR_TRANSFORM, 0u, FopRead_ACTOR_TRANSFORM },
319
    { CHUNKID_ACTOR_MATERIAL, 0u, FopRead_ACTOR_MATERIAL },
320
    { CHUNKID_ACTOR_LIGHT, 0u, FopRead_ACTOR_LIGHT },
321
    { CHUNKID_ACTOR_CAMERA, 0u, FopRead_ACTOR_CAMERA },
322
    { CHUNKID_ACTOR_BOUNDS, 0u, FopRead_ACTOR_BOUNDS },
323
    { CHUNKID_ACTOR_CLIP_PLANE, 0u, FopRead_ACTOR_CLIP_PLANE },
324
    { CHUNKID_ACTOR_ADD_CHILD, 0u, FopRead_ACTOR_ADD_CHILD },
325
    { CHUNKID_TRANSFORM_MAT34, 0u, FopRead_TRANSFORM },
326
    { CHUNKID_TRANSFORM_MAT34_LP, 0u, FopRead_TRANSFORM },
327
    { CHUNKID_TRANSFORM_QUAT, 0u, FopRead_TRANSFORM },
328
    { CHUNKID_TRANSFORM_EULER, 0u, FopRead_TRANSFORM },
329
    { CHUNKID_TRANSFORM_LOOK_UP, 0u, FopRead_TRANSFORM },
330
    { CHUNKID_TRANSFORM_TRANSLATION, 0u, FopRead_TRANSFORM },
331
    { CHUNKID_TRANSFORM_IDENTITY, 0u, FopRead_TRANSFORM },
332
    { CHUNKID_BOUNDS, 0u, FopRead_BOUNDS },
333
    { CHUNKID_LIGHT, 0u, FopRead_LIGHT },
334
    { CHUNKID_CAMERA, 0u, FopRead_CAMERA },
335
    { CHUNKID_PLANE, 0u, FopRead_PLANE },
336
};
337
br_chunks_table ActorLoadTable = { BR_ASIZE(ActorLoadEntries), ActorLoadEntries };
338
 
339
br_chunks_table_entry MaterialLoadEntries[8] = {
340
    { CHUNKID_END, 0u, FopRead_END },
341
    { CHUNKID_MATERIAL_OLD, 0u, FopRead_MATERIAL_OLD },
342
    { CHUNKID_MATERIAL_COLOUR_MAP, 0u, FopRead_PIXELMAP_REF },
343
    { CHUNKID_MATERIAL_INDEX_BLEND, 0u, FopRead_PIXELMAP_REF },
344
    { CHUNKID_MATERIAL_INDEX_SHADE, 0u, FopRead_PIXELMAP_REF },
345
    { CHUNKID_MATERIAL_SCREENDOOR, 0u, FopRead_PIXELMAP_REF },
346
    { CHUNKID_MATERIAL_INDEX_FOG, 0u, FopRead_PIXELMAP_REF },
347
    { CHUNKID_MATERIAL, 0u, FopRead_MATERIAL },
348
};
349
br_chunks_table MaterialLoadTable = { BR_ASIZE(MaterialLoadEntries), MaterialLoadEntries };
350
 
351
// IDA: int __usercall FopWrite_VERTICES@<EAX>(br_datafile *df@<EAX>, br_vertex *vertices@<EDX>, int nvertices@<EBX>)
352
int FopWrite_VERTICES(br_datafile* df, br_vertex* vertices, int nvertices) {
353
    LOG_TRACE("(%p, %p, %d)", df, vertices, nvertices);
354
 
355
    df->prims->chunk_write(df, CHUNKID_MODEL_VERTICES, df->prims->struct_size(df, &br_vertex_F, NULL) * nvertices + df->prims->count_size(df));
356
    df->prims->count_write(df, nvertices);
357
    DfStructWriteArray(df, &br_vertex_F, vertices, nvertices);
358
    return 0;
359
}
360
 
361
// IDA: int __usercall FopRead_VERTICES@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
362
int FopRead_VERTICES(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
363
    br_model* mp;
364
    //int i; // Pierre-Marie Baty -- unused variable
365
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
366
 
367
    mp = DfTop(DF_MODEL, NULL);
368
    mp->vertices = BrResAllocate(mp, sizeof(br_vertex) * count, BR_MEMORY_VERTICES);
369
    DfStructReadArray(df, &br_vertex_F, mp->vertices, count);
370
    mp->nvertices = count;
371
    return 0;
372
}
373
 
374
// IDA: int __usercall FopRead_OLD_VERTICES@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
375
int FopRead_OLD_VERTICES(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
376
    void* ptr;
377
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
378
 
379
    count = length / df->prims->struct_size(df, &br_vertex_F, NULL);
380
    ptr = BrResAllocate(v1db.res, count * sizeof(br_vertex), BR_MEMORY_VERTICES);
381
    DfStructReadArray(df, &br_vertex_F, ptr, count);
382
    DfPush(DF_VERTEX, ptr, count);
383
    return 0;
384
}
385
 
386
// IDA: int __usercall FopWrite_VERTEX_UV@<EAX>(br_datafile *df@<EAX>, br_vertex *vertices@<EDX>, int nvertices@<EBX>)
387
int FopWrite_VERTEX_UV(br_datafile* df, br_vertex* vertices, int nvertices) {
388
    LOG_TRACE("(%p, %p, %d)", df, vertices, nvertices);
389
 
390
    df->prims->chunk_write(df, CHUNKID_MODEL_VERTEX_UV, df->prims->struct_size(df, &br_vertex_uv_F, NULL) * nvertices + df->prims->count_size(df));
391
    df->prims->count_write(df, nvertices);
392
    DfStructWriteArray(df, &br_vertex_uv_F, vertices, nvertices);
393
    return 0;
394
}
395
 
396
// IDA: int __usercall FopRead_VERTEX_UV@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
397
int FopRead_VERTEX_UV(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
398
    br_model* mp;
399
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
400
 
401
    mp = DfTop(DF_MODEL, NULL);
402
    if (count > mp->nvertices) {
403
        BrFailure("Vertex UV: too many entries");
404
    }
405
    DfStructReadArray(df, &br_vertex_uv_F, mp->vertices, count);
406
    return 0;
407
}
408
 
409
// IDA: int __usercall FopRead_OLD_VERTICES_UV@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
410
int FopRead_OLD_VERTICES_UV(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
411
    void* ptr;
412
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
413
 
414
    count = length / df->prims->struct_size(df, &br_old_vertex_uv_F, NULL);
415
    ptr = BrResAllocate(v1db.res, count * sizeof(br_vertex), BR_MEMORY_VERTICES);
416
    DfStructReadArray(df, &br_old_vertex_uv_F, ptr, count);
417
    DfPush(DF_VERTEX, ptr, count);
418
    return 0;
419
}
420
 
421
// IDA: int __usercall FopRead_MATERIAL_INDEX@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
422
int FopRead_MATERIAL_INDEX(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
423
    char name[256];
424
    br_material** mip;
425
    br_uint_32 i;
426
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
427
 
428
    mip = (br_material**)BrResAllocate(v1db.res, sizeof(br_material*) * (count + 1), BR_MEMORY_MATERIAL_INDEX);
429
    mip[0] = NULL;
430
    for (i = 1; i < count + 1; i++) {
431
        df->prims->name_read(df, name);
432
        mip[i] = BrMaterialFind(name);
433
    }
434
    DfPush(DF_MATERIAL_INDEX, mip, count + 1);
435
    return 0;
436
}
437
 
438
// IDA: int __usercall FopWrite_MATERIAL_INDEX@<EAX>(br_datafile *df@<EAX>, br_material **materials@<EDX>, int nmaterials@<EBX>)
439
int FopWrite_MATERIAL_INDEX(br_datafile* df, br_material** materials, int nmaterials) {
440
    int i;
441
    int s;
442
    LOG_TRACE("(%p, %p, %d)", df, materials, nmaterials);
443
 
444
    s = df->prims->count_size(df);
445
    for (i = 0; i < nmaterials; i++) {
446
        s += df->prims->name_size(df, materials[i]->identifier);
447
    }
448
    df->prims->chunk_write(df, CHUNKID_MATERIAL_INDEX, s);
449
    df->prims->count_write(df, nmaterials);
450
    for (i = 0; i < nmaterials; i++) {
451
        df->prims->name_write(df, materials[i]->identifier);
452
    }
453
    return 0;
454
}
455
 
456
// IDA: int __usercall FopRead_OLD_MATERIAL_INDEX@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
457
int FopRead_OLD_MATERIAL_INDEX(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
458
    char* mblock;
459
    char* cp;
460
    int i;
461
    int num_materials;
462
    br_material** mip;
463
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
464
 
465
    mblock = BrScratchAllocate(length);
466
    if (BrFileRead(mblock, 1, length, df->h) != length) {
467
        BrFailure("could not read material index");
468
    }
469
    num_materials = 0;
470
    cp = mblock;
471
    for (i = 0; i < (int) length; i++) { // Pierre-Marie Baty -- added type cast
472
        if (*cp == '\0') {
473
            num_materials++;
474
        }
475
        cp++;
476
    }
477
    mip = BrResAllocate(v1db.res, num_materials * sizeof(br_material*), BR_MEMORY_MATERIAL_INDEX);
478
    cp = mblock;
479
    for (i = 0; i < num_materials; i++) {
480
        mip[i] = BrMaterialFind(cp);
481
        while (*cp != '\0') {
482
            cp++;
483
        }
484
        cp++;
485
    }
486
    BrScratchFree(mblock);
487
    DfPush(DF_MATERIAL_INDEX, mip, num_materials);
488
    return 0;
489
}
490
 
491
// IDA: int __usercall FopRead_FACES@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
492
int FopRead_FACES(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
493
    br_model* mp;
494
    int i;
495
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
496
    mp = DfTop(DF_MODEL, 0);
497
    mp->faces = (br_face*)BrResAllocate(mp, sizeof(br_face) * count, BR_MEMORY_FACES);
498
    mp->nfaces = count;
499
    DfStructReadArray(df, &br_face_F, mp->faces, count);
500
    for (i = 0; i < mp->nfaces; i++) {
501
        if (!mp->faces[i].smoothing) {
502
            mp->faces[i].smoothing = -1;
503
        }
504
        mp->faces[i].index = i;
505
    }
506
    return 0;
507
}
508
 
509
// IDA: int __usercall FopWrite_FACES@<EAX>(br_datafile *df@<EAX>, br_face *faces@<EDX>, int nfaces@<EBX>)
510
int FopWrite_FACES(br_datafile* df, br_face* faces, int nfaces) {
511
    LOG_TRACE("(%p, %p, %d)", df, faces, nfaces);
512
 
513
    df->prims->chunk_write(df, CHUNKID_MODEL_FACES, df->prims->struct_size(df, &br_face_F, NULL) * nfaces + df->prims->count_size(df));
514
    df->prims->count_write(df, nfaces);
515
    DfStructWriteArray(df, &br_face_F, faces, nfaces);
516
    return 0;
517
}
518
 
519
// IDA: int __usercall FopRead_OLD_FACES_1@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
520
int FopRead_OLD_FACES_1(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
521
    br_model* mp;
522
    int i;
523
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
524
 
525
    mp = DfTop(DF_MODEL, NULL);
526
    mp->faces = BrResAllocate(mp, count * sizeof(br_face), BR_MEMORY_FACES);
527
    mp->nfaces = count;
528
    DfStructReadArray(df, &br_old_face_1_F, mp->faces, (br_uint_16)count);
529
    for (i = 0; i < mp->nfaces; i++) {
530
        if (mp->faces[i].smoothing == 0) {
531
            mp->faces[i].smoothing = -1;
532
        } else {
533
            mp->faces[i].smoothing = 1 << ((mp->faces[i].smoothing - 1) % 16);
534
        }
535
    }
536
    return 0;
537
}
538
 
539
// IDA: int __usercall FopRead_OLD_FACES@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
540
int FopRead_OLD_FACES(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
541
    br_face* fp;
542
    br_material** mip;
543
    int mi_count;
544
    /*unsigned*/ int i; // Pierre-Marie Baty -- fixed type
545
    void* ptr;
546
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
547
 
548
    ptr = DfPop(DF_VERTEX, /*(int*)*/&i); // Pierre-Marie Baty -- removed type cast
549
    mip = DfPop(DF_MATERIAL_INDEX, &mi_count);
550
    DfPush(DF_VERTEX, ptr, i);
551
    mi_count = length / df->prims->struct_size(df, &br_old_face_F, NULL);
552
    fp = BrResAllocate(v1db.res, sizeof(br_face) * mi_count, BR_MEMORY_FACES);
553
    DfStructReadArray(df, &br_old_face_F, fp, mi_count);
554
    for (i = 0; i < mi_count; i++) {
555
        fp[i].material = mip[*(br_uint_16*)&fp[i].material];
556
        if (fp[i].smoothing == 0) {
557
            fp[i].smoothing = -1;
558
        }
559
    }
560
    BrResFree(mip);
561
    DfPush(DF_FACE, fp, mi_count);
562
    return 0;
563
}
564
 
565
// IDA: int __usercall FopWrite_FACE_MATERIAL@<EAX>(br_datafile *df@<EAX>, br_face *faces@<EDX>, int nfaces@<EBX>, br_material **mindex@<ECX>, int nmaterials)
566
int FopWrite_FACE_MATERIAL(br_datafile* df, br_face* faces, int nfaces, br_material** mindex, int nmaterials) {
567
    br_uint_16* block;
568
    //br_uint_16* ip; // Pierre-Marie Baty -- unused variable
569
    //br_face* fp; // Pierre-Marie Baty -- unused variable
570
    int i;
571
    int j;
572
    LOG_TRACE("(%p, %p, %d, %p, %d)", df, faces, nfaces, mindex, nmaterials);
573
 
574
    FopWrite_MATERIAL_INDEX(df, mindex, nmaterials);
575
    block = BrResAllocate(v1db.res, nfaces * sizeof(br_uint_16), BR_MEMORY_MATERIAL_INDEX);
576
    for (i = 0; i < nfaces; i++) {
577
        block[i] = 0;
578
        if (faces[i].material != NULL) {
579
            for (j = 0; j < nmaterials; j++) {
580
                if (faces[i].material == mindex[j]) {
581
                    block[i] = j + 1;
582
                    break;
583
                }
584
            }
585
        }
586
    }
587
    df->prims->chunk_write(df, CHUNKID_MODEL_FACE_MATERIAL, df->prims->block_size(df, block, nfaces, 0, 1, sizeof(br_uint_16)));
588
    df->prims->block_write(df, block, nfaces, 0, 1, sizeof(br_uint_16));
589
    BrResFree(block);
590
    return 0;
591
}
592
 
593
// IDA: int __usercall FopRead_FACE_MATERIAL@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
594
int FopRead_FACE_MATERIAL(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
595
    br_material** mindex;
596
    int nmaterials;
597
    br_model* mp;
598
    br_face* fp;
599
    br_uint_16* block;
600
    br_uint_16* ip;
601
    int block_count;
602
    int i;
603
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
604
 
605
    mindex = DfPop(DF_MATERIAL_INDEX, &nmaterials);
606
    mp = DfTop(DF_MODEL, 0);
607
 
608
    block = BrScratchAllocate(length);
609
    block_count = mp->nfaces;
610
    block = df->prims->block_read(df, block, &block_count, sizeof(br_uint_16), 0);
611
 
612
    if (block_count > mp->nfaces)
613
        BrFailure("Face Materials: too many entries");
614
 
615
    fp = mp->faces;
616
    ip = block;
617
    for (i = 0; i < block_count; i++) {
618
        fp->material = (*ip < nmaterials) ? mindex[*ip] : NULL;
619
        fp++;
620
        ip++;
621
    }
622
 
623
    BrScratchFree(block);
624
    BrResFree(mindex);
625
    return 0;
626
}
627
 
628
// IDA: int __usercall FopRead_MODEL@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
629
int FopRead_MODEL(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
630
    br_model* mp;
631
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
632
 
633
    mp = BrModelAllocate(NULL, 0, 0);
634
    mp->identifier = NULL;
635
    df->res = mp;
636
    df->prims->struct_read(df, &br_model_F, mp);
637
    df->res = NULL;
638
    mp->flags &= (BR_MODF_DONT_WELD | BR_MODF_KEEP_ORIGINAL | BR_MODF_GENERATE_TAGS | BR_MODF_QUICK_UPDATE);
639
    DfPush(DF_MODEL, mp, 1);
640
    return 0;
641
}
642
 
643
// IDA: int __usercall FopWrite_MODEL@<EAX>(br_datafile *df@<EAX>, br_model *mp@<EDX>)
644
int FopWrite_MODEL(br_datafile* df, br_model* mp) {
645
    br_model temp_model;
646
    LOG_TRACE("(%p, %p)", df, mp);
647
 
648
    memcpy(&temp_model, mp, sizeof(br_model));
649
    df->prims->chunk_write(df, CHUNKID_MODEL, df->prims->struct_size(df, &br_model_F, mp));
650
    df->prims->struct_write(df, &br_model_F, mp);
651
    return 0;
652
}
653
 
654
// IDA: int __usercall FopRead_OLD_MODEL_1@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
655
int FopRead_OLD_MODEL_1(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
656
    br_model* mp;
657
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
658
 
659
    mp = BrModelAllocate(NULL, 0, 0);
660
    df->res = mp;
661
    df->prims->struct_read(df, &br_old_model_1_F, mp);
662
    df->res = NULL;
663
    DfPush(DF_MODEL, df->res, 1);
664
    return 0;
665
}
666
 
667
// IDA: int __usercall FopRead_OLD_MODEL@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
668
int FopRead_OLD_MODEL(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
669
    br_model* mp;
670
    int i;
671
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
672
 
673
    mp = BrModelAllocate(NULL, 0, 0);
674
    df->res = mp;
675
    df->prims->struct_read(df, &br_model_F, mp);
676
    df->res = NULL;
677
    mp->faces = DfPop(DF_FACE, &i);
678
    mp->nfaces = i;
679
    mp->vertices = DfPop(DF_VERTEX, &i);
680
    mp->nvertices = i;
681
    BrResAdd(mp, mp->faces);
682
    BrResAdd(mp, mp->vertices);
683
    mp->flags = mp->flags & (BR_MODF_DONT_WELD | BR_MODF_KEEP_ORIGINAL | BR_MODF_GENERATE_TAGS | BR_MODF_QUICK_UPDATE);
684
    DfPush(DF_MODEL, mp, 1);
685
    return 0;
686
}
687
 
688
// IDA: int __usercall FopRead_PIVOT@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
689
int FopRead_PIVOT(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
690
    br_model* mp;
691
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
692
 
693
    mp = DfPop(DF_MODEL, NULL);
694
    df->res = mp;
695
    df->prims->struct_read(df, &br_pivot_F, mp);
696
    df->res = NULL;
697
    DfPush(DF_MODEL, mp, 1);
698
    return 0;
699
}
700
 
701
// IDA: int __usercall FopRead_MATERIAL_OLD@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
702
int FopRead_MATERIAL_OLD(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
703
    br_material* mp;
704
    mp = BrMaterialAllocate(NULL);
705
    df->res = mp;
706
    df->prims->struct_read(df, &br_material_old_F, mp);
707
    df->res = NULL;
708
    DfPush(DF_MATERIAL, mp, 1);
709
    return 0;
710
}
711
 
712
// IDA: int __usercall FopRead_MATERIAL@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
713
int FopRead_MATERIAL(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
714
    br_material* mp;
715
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
716
 
717
    mp = BrMaterialAllocate(NULL);
718
    df->res = mp;
719
    df->prims->struct_read(df, &br_material_F, mp);
720
    df->res = NULL;
721
    DfPush(DF_MATERIAL, mp, 1);
722
    return 0;
723
}
724
 
725
// IDA: int __usercall FopWrite_MATERIAL@<EAX>(br_datafile *df@<EAX>, br_material *mp@<EDX>)
726
int FopWrite_MATERIAL(br_datafile* df, br_material* mp) {
727
    LOG_TRACE("(%p, %p)", df, mp);
728
 
729
    df->prims->chunk_write(df, CHUNKID_MATERIAL, df->prims->struct_size(df, &br_material_F, mp));
730
    df->prims->struct_write(df,&br_material_F, mp);
731
    return 0;
732
}
733
 
734
// IDA: int __usercall FopRead_PIXELMAP_REF@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
735
int FopRead_PIXELMAP_REF(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
736
    br_pixelmap* pm;
737
    char name[256];
738
    char* mp;
739
    int i;
740
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
741
 
742
    for (i = 0; i < BR_ASIZE(MaterialMaps); i++) {
743
        if (id == MaterialMaps[i].id) {
744
            break;
745
        }
746
    }
747
 
748
    mp = DfTop(DF_MATERIAL, NULL);
749
    df->prims->name_read(df, name);
750
    if (MaterialMaps[i].table != 0) {
751
        pm = BrTableFind(name);
752
    } else {
753
        pm = BrMapFind(name);
754
    }
755
    *(intptr_t*)(mp + MaterialMaps[i].offset) = (intptr_t/***/)pm; // Pierre-Marie Baty -- fixed type
756
    return 0;
757
}
758
 
759
// IDA: int __usercall FopWrite_PIXELMAP_REF@<EAX>(br_datafile *df@<EAX>, int id@<EDX>, br_pixelmap *pixelmap@<EBX>)
760
int FopWrite_PIXELMAP_REF(br_datafile* df, int id, br_pixelmap* pixelmap) {
761
    LOG_TRACE("(%p, %d, %p)", df, id, pixelmap);
762
 
763
    df->prims->chunk_write(df, id, df->prims->name_size(df, pixelmap->identifier));
764
    df->prims->name_write(df, pixelmap->identifier);
765
    return 0;
766
}
767
 
768
// IDA: int __usercall FopWrite_ACTOR@<EAX>(br_datafile *df@<EAX>, br_actor *ap@<EDX>)
769
int FopWrite_ACTOR(br_datafile* df, br_actor* ap) {
770
    LOG_TRACE("(%p, %p)", df, ap);
771
 
772
    df->prims->chunk_write(df, CHUNKID_ACTOR, df->prims->struct_size(df, &br_actor_F, ap));
773
    df->prims->struct_write(df, &br_actor_F, ap);
774
    return 0;
775
}
776
 
777
// IDA: int __usercall FopRead_ACTOR@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
778
int FopRead_ACTOR(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
779
    br_actor* ap;
780
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
781
 
782
    ap = BrActorAllocate(BR_ACTOR_NONE, NULL);
783
    df->res = ap;
784
    df->prims->struct_read(df, &br_actor_F, ap);
785
    df->res = NULL;
786
    ap->t.type = BR_TRANSFORM_IDENTITY;
787
    DfPush(DF_ACTOR, ap, 1);
788
    return 0;
789
}
790
 
791
// IDA: int __usercall FopWrite_ACTOR_MODEL@<EAX>(br_datafile *df@<EAX>, br_model *model@<EDX>)
792
int FopWrite_ACTOR_MODEL(br_datafile* df, br_model* model) {
793
    LOG_TRACE9("(%p, %p)", df, model);
794
 
795
    df->prims->chunk_write(df, CHUNKID_ACTOR_MODEL, df->prims->name_size(df, model->identifier));
796
    df->prims->name_write(df, model->identifier);
797
    return 0;
798
}
799
 
800
// IDA: int __usercall FopRead_ACTOR_MODEL@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
801
int FopRead_ACTOR_MODEL(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
802
    char name[256];
803
    br_actor* a;
804
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
805
 
806
    a = DfTop(DF_ACTOR, 0);
807
    df->prims->name_read(df, name);
808
    a->model = BrModelFind(name);
809
    return 0;
810
}
811
 
812
// IDA: int __usercall FopWrite_ACTOR_MATERIAL@<EAX>(br_datafile *df@<EAX>, br_material *material@<EDX>)
813
int FopWrite_ACTOR_MATERIAL(br_datafile* df, br_material* material) {
814
    LOG_TRACE("(%p, %p)", df, material);
815
 
816
    df->prims->chunk_write(df, CHUNKID_ACTOR_MATERIAL, df->prims->name_size(df, material->identifier));
817
    df->prims->name_write(df, material->identifier);
818
    return 0;
819
}
820
 
821
// IDA: int __usercall FopRead_ACTOR_MATERIAL@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
822
int FopRead_ACTOR_MATERIAL(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
823
    char name[256];
824
    br_actor* a;
825
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
826
 
827
    a = DfTop(DF_ACTOR, NULL);
828
    df->prims->name_read(df, name);
829
    a->material = BrMaterialFind(name);
830
    return 0;
831
}
832
 
833
// IDA: int __usercall FopWrite_ACTOR_TRANSFORM@<EAX>(br_datafile *df@<EAX>)
834
int FopWrite_ACTOR_TRANSFORM(br_datafile* df) {
835
    LOG_TRACE("(%p)", df);
836
 
837
    df->prims->chunk_write(df, CHUNKID_ACTOR_TRANSFORM, 0);
838
    return 0;
839
}
840
 
841
// IDA: int __usercall FopRead_ACTOR_TRANSFORM@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
842
int FopRead_ACTOR_TRANSFORM(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
843
    br_actor* a;
844
    br_transform* tp;
845
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
846
 
847
    tp = DfPop(DF_TRANSFORM, NULL);
848
    a = DfTop(DF_ACTOR, NULL);
849
    memcpy(&a->t, tp, sizeof(br_transform));
850
    BrResFree(tp);
851
    return 0;
852
}
853
 
854
// IDA: int __usercall FopWrite_ACTOR_LIGHT@<EAX>(br_datafile *df@<EAX>)
855
int FopWrite_ACTOR_LIGHT(br_datafile* df) {
856
    LOG_TRACE("(%p)", df);
857
 
858
    df->prims->chunk_write(df, CHUNKID_ACTOR_LIGHT, 0);
859
    return 0;
860
}
861
 
862
// IDA: int __usercall FopRead_ACTOR_LIGHT@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
863
int FopRead_ACTOR_LIGHT(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
864
    br_actor* a;
865
    br_light* lp;
866
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
867
 
868
    lp = DfPop(DF_LIGHT, NULL);
869
    a = DfTop(DF_ACTOR, NULL);
870
    a->type_data = lp;
871
    return 0;
872
}
873
 
874
// IDA: int __usercall FopWrite_ACTOR_CAMERA@<EAX>(br_datafile *df@<EAX>)
875
int FopWrite_ACTOR_CAMERA(br_datafile* df) {
876
    LOG_TRACE("(%p)", df);
877
 
878
    df->prims->chunk_write(df, CHUNKID_ACTOR_CAMERA, 0);
879
    return 0;
880
}
881
 
882
// IDA: int __usercall FopRead_ACTOR_CAMERA@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
883
int FopRead_ACTOR_CAMERA(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
884
    br_actor* a;
885
    br_light* cp;
886
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
887
 
888
    cp = DfPop(DF_CAMERA, NULL);
889
    a = DfTop(DF_ACTOR, NULL);
890
    a->type_data = cp;
891
    return 0;
892
}
893
 
894
// IDA: int __usercall FopWrite_ACTOR_BOUNDS@<EAX>(br_datafile *df@<EAX>)
895
int FopWrite_ACTOR_BOUNDS(br_datafile* df) {
896
    LOG_TRACE("(%p)", df);
897
 
898
    df->prims->chunk_write(df, CHUNKID_ACTOR_BOUNDS, 0);
899
    return 0;
900
}
901
 
902
// IDA: int __usercall FopRead_ACTOR_BOUNDS@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
903
int FopRead_ACTOR_BOUNDS(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
904
    br_actor* a;
905
    br_bounds* bp;
906
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
907
 
908
    bp = DfPop(DF_BOUNDS, 0);
909
    a = DfTop(DF_ACTOR, 0);
910
    a->type_data = bp;
911
    return 0;
912
}
913
 
914
// IDA: int __usercall FopWrite_ACTOR_CLIP_PLANE@<EAX>(br_datafile *df@<EAX>)
915
int FopWrite_ACTOR_CLIP_PLANE(br_datafile* df) {
916
    LOG_TRACE("(%p)", df);
917
 
918
    df->prims->chunk_write(df, CHUNKID_ACTOR_CLIP_PLANE, 0);
919
    return 0;
920
}
921
 
922
// IDA: int __usercall FopRead_ACTOR_CLIP_PLANE@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
923
int FopRead_ACTOR_CLIP_PLANE(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
924
    br_actor* a;
925
    br_vector4* vp;
926
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
927
 
928
    vp = DfPop(DF_CLIP_PLANE, NULL);
929
    a = DfTop(DF_ACTOR, NULL);
930
    a->type_data = vp;
931
    return 0;
932
}
933
 
934
// IDA: int __usercall FopWrite_ACTOR_ADD_CHILD@<EAX>(br_datafile *df@<EAX>)
935
int FopWrite_ACTOR_ADD_CHILD(br_datafile* df) {
936
    LOG_TRACE("(%p)", df);
937
 
938
    df->prims->chunk_write(df, CHUNKID_ACTOR_ADD_CHILD, 0);
939
    return 0;
940
}
941
 
942
// IDA: int __usercall FopRead_ACTOR_ADD_CHILD@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
943
int FopRead_ACTOR_ADD_CHILD(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
944
    br_actor* a;
945
    br_actor* p;
946
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
947
 
948
    a = DfPop(DF_ACTOR, 0);
949
    p = DfTop(DF_ACTOR, 0);
950
    BrActorAdd(p, a);
951
 
952
    return 0;
953
}
954
 
955
// IDA: int __usercall FopWrite_TRANSFORM@<EAX>(br_datafile *df@<EAX>, br_transform *t@<EDX>)
956
int FopWrite_TRANSFORM(br_datafile* df, br_transform* t) {
957
    transform_type* tt;
958
    LOG_TRACE("(%p, %p)", df, t);
959
 
960
    tt = &TransformTypes[t->type];
961
    if (tt->fs == NULL) {
962
        df->prims->chunk_write(df, tt->id, 0);
963
    } else {
964
        df->prims->chunk_write(df, tt->id, df->prims->struct_size(df, tt->fs, t));
965
        df->prims->struct_size(df, tt->fs, &t);
966
        df->prims->struct_write(df, tt->fs, t);
967
    }
968
    return 0;
969
}
970
 
971
// IDA: int __usercall FopRead_TRANSFORM@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
972
int FopRead_TRANSFORM(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
973
    int t;
974
    br_transform* tp;
975
    LOG_TRACE9("(%p, %d, %d, %d)", df, id, length, count);
976
 
977
    for (t = 0; t < BR_ASIZE(TransformTypes); t++) {
978
        if (id == TransformTypes[t].id) {
979
            break;
980
        }
981
    }
982
    if (t == BR_ASIZE(TransformTypes)) {
983
        LOG_PANIC("transform type not found!");
984
    }
985
    tp = (br_transform*)BrResAllocate(v1db.res, sizeof(br_transform), BR_MEMORY_TRANSFORM);
986
    tp->type = t;
987
    df->res = tp;
988
    if (TransformTypes[t].fs) {
989
        df->prims->struct_read(df, TransformTypes[t].fs, tp);
990
    }
991
    df->res = NULL;
992
    DfPush(DF_TRANSFORM, tp, 1);
993
    return 0;
994
}
995
 
996
// IDA: int __usercall FopWrite_BOUNDS@<EAX>(br_datafile *df@<EAX>, br_bounds *bp@<EDX>)
997
int FopWrite_BOUNDS(br_datafile* df, br_bounds* bp) {
998
    LOG_TRACE("(%p, %p)", df, bp);
999
 
1000
    df->prims->chunk_write(df, CHUNKID_BOUNDS, df->prims->struct_size(df, &br_bounds3_F, bp));
1001
    df->prims->struct_write(df, &br_bounds3_F, bp);
1002
    return 0;
1003
}
1004
 
1005
// IDA: int __usercall FopRead_BOUNDS@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
1006
int FopRead_BOUNDS(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
1007
    br_bounds3* bp;
1008
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
1009
 
1010
    bp = BrResAllocate(v1db.res, sizeof(br_bounds3), BR_MEMORY_BOUNDS);
1011
    df->res = bp;
1012
    df->prims->struct_read(df, &br_bounds3_F, bp);
1013
    df->res = NULL;
1014
    DfPush(DF_BOUNDS, bp, 1);
1015
    return 0;
1016
}
1017
 
1018
// IDA: int __usercall FopWrite_PLANE@<EAX>(br_datafile *df@<EAX>, br_vector4 *pp@<EDX>)
1019
int FopWrite_PLANE(br_datafile* df, br_vector4* pp) {
1020
    LOG_TRACE("(%p, %p)", df, pp);
1021
 
1022
    df->prims->chunk_write(df, CHUNKID_PLANE, df->prims->struct_size(df, &br_plane_F, pp));
1023
    df->prims->struct_write(df, &br_plane_F, pp);
1024
    return 0;
1025
}
1026
 
1027
// IDA: int __usercall FopRead_PLANE@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
1028
int FopRead_PLANE(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
1029
    br_vector4* pp;
1030
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
1031
 
1032
    pp = BrResAllocate(v1db.res, sizeof(br_vector4), BR_MEMORY_CLIP_PLANE);
1033
    df->res = pp;
1034
    df->prims->struct_read(df, &br_plane_F, pp);
1035
    df->res = NULL;
1036
    DfPush(DF_CLIP_PLANE, pp, 1);
1037
    return 0;
1038
}
1039
 
1040
// IDA: int __usercall FopWrite_LIGHT@<EAX>(br_datafile *df@<EAX>, br_light *lp@<EDX>)
1041
int FopWrite_LIGHT(br_datafile* df, br_light* lp) {
1042
    LOG_TRACE("(%p, %p)", df, lp);
1043
 
1044
    df->prims->chunk_write(df, CHUNKID_LIGHT, df->prims->struct_size(df, &br_light_F, lp));
1045
    df->prims->struct_write(df, &br_light_F, lp);
1046
    return 0;
1047
}
1048
 
1049
// IDA: int __usercall FopRead_LIGHT@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
1050
int FopRead_LIGHT(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
1051
    br_light* lp;
1052
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
1053
 
1054
    lp = BrResAllocate(v1db.res, sizeof(br_light), BR_MEMORY_LIGHT);
1055
    df->res = lp;
1056
    df->prims->struct_read(df, &br_light_F, lp);
1057
    df->res = NULL;
1058
    DfPush(DF_LIGHT, lp, 1);
1059
    return 0;
1060
}
1061
 
1062
// IDA: int __usercall FopWrite_CAMERA@<EAX>(br_datafile *df@<EAX>, br_camera *cp@<EDX>)
1063
int FopWrite_CAMERA(br_datafile* df, br_camera* cp) {
1064
    LOG_TRACE("(%p, %p)", df, cp);
1065
 
1066
    df->prims->chunk_write(df, CHUNKID_CAMERA, df->prims->struct_size(df, &br_camera_F, cp));
1067
    df->prims->struct_write(df, &br_camera_F, cp);
1068
    return 0;
1069
}
1070
 
1071
// IDA: int __usercall FopRead_CAMERA@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>, br_uint_32 count@<ECX>)
1072
int FopRead_CAMERA(br_datafile* df, br_uint_32 id, br_uint_32 length, br_uint_32 count) {
1073
    br_camera* cp;
1074
    LOG_TRACE("(%p, %d, %d, %d)", df, id, length, count);
1075
 
1076
    cp = BrResAllocate(v1db.res, sizeof(br_camera), BR_MEMORY_CAMERA);
1077
    df->res = cp;
1078
    df->prims->struct_read(df, &br_camera_F, cp);
1079
    df->res = NULL;
1080
    DfPush(DF_CAMERA, cp, 1);
1081
    return 0;
1082
}
1083
 
1084
// IDA: br_uint_32 __cdecl BrModelLoadMany(char *filename, br_model **models, br_uint_16 num)
1085
br_uint_32 BrModelLoadMany(char* filename, br_model** models, br_uint_16 num) {
1086
    int count;
1087
    int r;
1088
    br_datafile* df;
1089
    LOG_TRACE9("(\"%s\", %p, %d)", filename, models, num);
1090
 
1091
    df = DfOpen(filename, 0, BRT_FLOAT);
1092
    if (df == NULL) {
1093
        return 0;
1094
    }
1095
    count = 0;
1096
    do {
1097
        if (count >= num) {
1098
            break;
1099
        }
1100
        r = DfChunksInterpret(df, &ModelLoadTable);
1101
        if (DfTopType() == DF_MODEL) {
1102
            models[count] = DfPop(DF_MODEL, 0);
1103
            count++;
1104
        }
1105
    } while (r != 0);
1106
    DfClose(df);
1107
    return count;
1108
}
1109
 
1110
// IDA: int __cdecl PtrCompare(void *a, void *b)
1111
int PtrCompare(void* a, void* b) {
1112
    LOG_TRACE("(%p, %p)", a, b);
1113
 
1114
    if (*(uintptr_t*)a > *(uintptr_t*)b) {
1115
        return -1;
1116
    }
1117
    return *(uintptr_t*)a < *(uintptr_t*)b;
1118
}
1119
 
1120
// IDA: br_uint_32 __cdecl WriteModel(br_model *mp, br_datafile *df)
1121
br_uint_32 WriteModel(br_model* mp, br_datafile* df) {
1122
    br_material** mindex;
1123
    //br_vertex* vp; // Pierre-Marie Baty -- unused variable
1124
    int nmaterials;
1125
    int i;
1126
    int has_uv;
1127
    LOG_TRACE("(%p, %p)", mp, df);
1128
 
1129
    nmaterials = 0;
1130
    if (mp->vertices == NULL || mp->faces == NULL) {
1131
        if (mp->identifier != NULL) {
1132
            BrWarning(mp->identifier);
1133
        }
1134
        BrWarning("Model must have vertex and face information to save.");
1135
        BrWarning("This information may have neem stripped on addition to");
1136
        BrWarning("the registry. To prevent this, set the BR_MODF_UPDATEABLE");
1137
        BrFailure("flag before adding the model to the registry.");
1138
    }
1139
    mindex = BrResAllocate(v1db.res, mp->nfaces * sizeof(br_material*), BR_MEMORY_MATERIAL_INDEX);
1140
    for (i = 0; i < mp->nfaces; i++) {
1141
        mindex[i] = mp->faces[i].material;
1142
    }
1143
    BrQsort(mindex, mp->nfaces, sizeof(br_material*), (br_qsort_cbfn*)PtrCompare);
1144
    nmaterials = 1;
1145
    for (i = 1; i < mp->nfaces; i++) {
1146
        if (mindex[nmaterials-1] == mindex[i]) {
1147
            mindex[nmaterials] = mindex[i];
1148
            nmaterials++;
1149
        }
1150
    }
1151
    if (mindex[nmaterials-1] == NULL) {
1152
        nmaterials = 0;
1153
    }
1154
    has_uv = 0;
1155
    for (i = 0; i < mp->nvertices; i++) {
1156
        if (mp->vertices[i].map.v[0] != 0.f || mp->vertices[i].map.v[1] != 0.f) {
1157
            has_uv = 1;
1158
            break;
1159
        }
1160
    }
1161
 
1162
    FopWrite_MODEL(df, mp);
1163
    if (mp->nvertices != 0) {
1164
        FopWrite_VERTICES(df, mp->vertices, mp->nvertices);
1165
        if (has_uv != 0) {
1166
            FopWrite_VERTEX_UV(df, mp->vertices, mp->nvertices);
1167
        }
1168
    }
1169
    if (mp->nfaces != 0) {
1170
        FopWrite_FACES(df, mp->faces, mp->nfaces);
1171
        if (nmaterials != 0) {
1172
            FopWrite_FACE_MATERIAL(df, mp->faces, mp->nfaces, mindex, nmaterials);
1173
        }
1174
    }
1175
    FopWrite_END(df);
1176
    BrResFree(mindex);
1177
    return 0;
1178
}
1179
 
1180
// IDA: br_uint_32 __cdecl BrModelSaveMany(char *filename, br_model **models, br_uint_16 num)
1181
br_uint_32 BrModelSaveMany(char* filename, br_model** models, br_uint_16 num) {
1182
    br_datafile* df;
1183
    int i;
1184
    int m;
1185
    LOG_TRACE("(\"%s\", %p, %d)", filename, models, num);
1186
 
1187
    df = DfOpen(filename, 1, BRT_FLOAT);
1188
    if (df == NULL) {
1189
        return 0;
1190
    }
1191
    FopWrite_FILE_INFO(df, FILE_TYPE_MODEL);
1192
    if (models == NULL) {
1193
        BrModelEnum(NULL, (br_model_enum_cbfn*)&WriteModel, df);
1194
        m = BrModelCount(NULL);
1195
    } else {
1196
        for (i = 0; i < num; i++) {
1197
            WriteModel(models[i], df);
1198
        }
1199
        m = num;
1200
    }
1201
    DfClose(df);
1202
    return m;
1203
}
1204
 
1205
// IDA: br_uint_32 __cdecl BrActorLoadMany(char *filename, br_actor **actors, br_uint_16 num)
1206
br_uint_32 BrActorLoadMany(char* filename, br_actor** actors, br_uint_16 num) {
1207
    br_datafile* df;
1208
    int count;
1209
    int r;
1210
    LOG_TRACE9("(\"%s\", %p, %d)", filename, actors, num);
1211
 
1212
    df = DfOpen(filename, 0, BRT_FLOAT);
1213
    if (df == NULL) {
1214
        return 0;
1215
    }
1216
 
1217
    count = 0;
1218
    do {
1219
        if (count >= num) {
1220
            break;
1221
        }
1222
        r = DfChunksInterpret(df, &ActorLoadTable);
1223
        if (DfTopType() == DF_ACTOR) {
1224
            actors[count] = DfPop(DF_ACTOR, NULL);
1225
            count++;
1226
        }
1227
    } while (r != 0);
1228
    DfClose(df);
1229
    return count;
1230
}
1231
 
1232
// IDA: int __usercall WriteActor@<EAX>(br_actor *a@<EAX>, br_datafile *df@<EDX>)
1233
int WriteActor(br_actor* a, br_datafile* df) {
1234
    br_actor* ap;
1235
    br_actor* last_ap;
1236
    LOG_TRACE("(%p, %p)", a, df);
1237
 
1238
    FopWrite_ACTOR(df, a);
1239
    if (a->t.type != BR_TRANSFORM_IDENTITY) {
1240
        FopWrite_TRANSFORM(df, &a->t);
1241
        FopWrite_ACTOR_TRANSFORM(df);
1242
    }
1243
    if (a->material != NULL) {
1244
        FopWrite_ACTOR_MATERIAL(df, a->material);
1245
    }
1246
    if (a->model != NULL) {
1247
        FopWrite_ACTOR_MODEL(df, a->model);
1248
    }
1249
    if (a->type_data != NULL) {
1250
        switch (a->type) {
1251
        case BR_ACTOR_LIGHT:
1252
            FopWrite_LIGHT(df, a->type_data);
1253
            FopWrite_ACTOR_LIGHT(df);
1254
            break;
1255
        case BR_ACTOR_CAMERA:
1256
            FopWrite_CAMERA(df, a->type_data);
1257
            FopWrite_ACTOR_CAMERA(df);
1258
            break;
1259
        case BR_ACTOR_BOUNDS:
1260
            FopWrite_BOUNDS(df, a->type_data);
1261
            FopWrite_ACTOR_BOUNDS(df);
1262
            break;
1263
        case BR_ACTOR_CLIP_PLANE:
1264
            FopWrite_PLANE(df, a->type_data);
1265
            FopWrite_ACTOR_CLIP_PLANE(df);
1266
            break;
1267
        }
1268
    }
1269
    if (a->children != NULL){
1270
        last_ap = a->children;
1271
        while (last_ap->next != NULL) {
1272
            last_ap = last_ap->next;
1273
        }
1274
        ap = last_ap;
1275
        while (1) {
1276
            WriteActor(ap, df);
1277
            FopWrite_ACTOR_ADD_CHILD(df);
1278
            if (a->children == ap) {
1279
                break;
1280
            }
1281
            ap = (br_actor*)ap->prev;
1282
        }
1283
    }
1284
    return 0;
1285
}
1286
 
1287
// IDA: br_uint_32 __cdecl BrActorSaveMany(char *filename, br_actor **actors, br_uint_16 num)
1288
br_uint_32 BrActorSaveMany(char* filename, br_actor** actors, br_uint_16 num) {
1289
    br_datafile* df;
1290
    int i;
1291
    LOG_TRACE("(\"%s\", %p, %d)", filename, actors, num);
1292
 
1293
    df = DfOpen(filename, 1, BRT_FLOAT);
1294
    if (df == NULL) {
1295
        return 0;
1296
    }
1297
    FopWrite_FILE_INFO(df, FILE_TYPE_ACTORS);
1298
    for (i = 0; i < num; i++) {
1299
        WriteActor(actors[i], df);
1300
        FopWrite_END(df);
1301
    }
1302
    DfClose(df);
1303
    return num;
1304
}
1305
 
1306
// IDA: br_uint_32 __cdecl BrMaterialLoadMany(char *filename, br_material **materials, br_uint_16 num)
1307
br_uint_32 BrMaterialLoadMany(char* filename, br_material** materials, br_uint_16 num) {
1308
    br_datafile* df;
1309
    int count;
1310
    int r;
1311
 
1312
    df = DfOpen(filename, 0, BRT_FLOAT);
1313
    if (df == NULL) {
1314
        return 0;
1315
    }
1316
    count = 0;
1317
    do {
1318
        if (count >= num) {
1319
            break;
1320
        }
1321
        r = DfChunksInterpret(df, &MaterialLoadTable);
1322
        if (DfTopType() == DF_MATERIAL) {
1323
            materials[count] = DfPop(DF_MATERIAL, 0);
1324
            ++count;
1325
        }
1326
    } while (r != 0);
1327
    DfClose(df);
1328
    return count;
1329
}
1330
 
1331
// IDA: br_uint_32 __cdecl WriteMaterial(br_material *mp, br_datafile *df)
1332
br_uint_32 WriteMaterial(br_material* mp, br_datafile* df) {
1333
    LOG_TRACE("(%p, %p)", mp, df);
1334
 
1335
    FopWrite_MATERIAL(df, mp);
1336
    if (mp->colour_map != NULL) {
1337
        FopWrite_PIXELMAP_REF(df, CHUNKID_MATERIAL_COLOUR_MAP, mp->colour_map);
1338
    }
1339
    if (mp->index_shade != NULL) {
1340
        FopWrite_PIXELMAP_REF(df, CHUNKID_MATERIAL_INDEX_SHADE, mp->index_shade);
1341
    }
1342
    if (mp->index_blend != NULL) {
1343
        FopWrite_PIXELMAP_REF(df, CHUNKID_MATERIAL_INDEX_BLEND, mp->index_blend);
1344
    }
1345
    if (mp->screendoor != NULL) {
1346
        FopWrite_PIXELMAP_REF(df, CHUNKID_MATERIAL_SCREENDOOR, mp->screendoor);
1347
    }
1348
    if (mp->index_fog != NULL) {
1349
        FopWrite_PIXELMAP_REF(df, CHUNKID_MATERIAL_INDEX_FOG, mp->index_fog);
1350
    }
1351
    FopWrite_END(df);
1352
    return 0;
1353
}
1354
 
1355
// IDA: br_uint_32 __cdecl BrMaterialSaveMany(char *filename, br_material **materials, br_uint_16 num)
1356
br_uint_32 BrMaterialSaveMany(char* filename, br_material** materials, br_uint_16 num) {
1357
    br_datafile* df;
1358
    int i;
1359
    int count;
1360
    LOG_TRACE("(\"%s\", %p, %d)", filename, materials, num);
1361
 
1362
    df = DfOpen(filename, 1, BRT_FLOAT);
1363
    if (df == NULL) {
1364
        return 0;
1365
    }
1366
#ifdef BRENDER_FIX_BUGS
1367
    FopWrite_FILE_INFO(df, FILE_TYPE_MATERIAL);
1368
#else
1369
    FopWrite_FILE_INFO(df, FILE_TYPE_MATERIAL_OLD);
1370
#endif
1371
    if (materials == NULL) {
1372
        BrMaterialEnum(NULL, (br_material_enum_cbfn*)WriteMaterial, df);
1373
        count = BrMaterialCount(NULL);
1374
    } else {
1375
        for (i = 0; i < num; i++) {
1376
            WriteMaterial(materials[i], df);
1377
        }
1378
        count = num;
1379
    }
1380
    DfClose(df);
1381
    return count;
1382
}
1383
 
1384
// IDA: br_model* __cdecl BrModelLoad(char *filename)
1385
br_model* BrModelLoad(char* filename) {
1386
    br_model* ptr;
1387
    LOG_TRACE("(\"%s\")", filename);
1388
 
1389
    if (BrModelLoadMany(filename, &ptr, 1) == 1) {
1390
        return ptr;
1391
    }
1392
    return NULL;
1393
}
1394
 
1395
// IDA: br_uint_32 __cdecl BrModelSave(char *filename, br_model *ptr)
1396
br_uint_32 BrModelSave(char* filename, br_model* ptr) {
1397
    LOG_TRACE("(\"%s\", %p)", filename, ptr);
1398
 
1399
    return BrModelSaveMany(filename, &ptr, 1);
1400
}
1401
 
1402
// IDA: br_material* __cdecl BrMaterialLoad(char *filename)
1403
br_material* BrMaterialLoad(char* filename) {
1404
    br_material* ptr;
1405
 
1406
    if (BrMaterialLoadMany(filename, &ptr, 1) == 1) {
1407
        return ptr;
1408
    }
1409
    return NULL;
1410
}
1411
 
1412
// IDA: br_uint_32 __cdecl BrMaterialSave(char *filename, br_material *ptr)
1413
br_uint_32 BrMaterialSave(char* filename, br_material* ptr) {
1414
    LOG_TRACE("(\"%s\", %p)", filename, ptr);
1415
 
1416
    return BrMaterialSaveMany(filename, &ptr, 1);
1417
}
1418
 
1419
// IDA: br_actor* __cdecl BrActorLoad(char *filename)
1420
br_actor* BrActorLoad(char* filename) {
1421
    br_actor* ptr;
1422
    LOG_TRACE("(\"%s\")", filename);
1423
 
1424
    if (BrActorLoadMany(filename, &ptr, 1) == 1) {
1425
        return ptr;
1426
    }
1427
    LOG_DEBUG("loadmany fail");
1428
    return NULL;
1429
}
1430
 
1431
// IDA: br_uint_32 __cdecl BrActorSave(char *filename, br_actor *ptr)
1432
br_uint_32 BrActorSave(char* filename, br_actor* ptr) {
1433
    LOG_TRACE("(\"%s\", %p)", filename, ptr);
1434
 
1435
    return BrActorSaveMany(filename, &ptr, 1);
1436
}
1437
 
1438
// IDA: br_error __cdecl BrModelFileCount(char *filename, br_uint_16 *num)
1439
br_error BrModelFileCount(char* filename, br_uint_16* num) {
1440
    br_datafile* df;
1441
    LOG_TRACE("(\"%s\", %p)", filename, num);
1442
 
1443
    df = DfOpen(filename, 0, BRT_FLOAT);
1444
    if (df == NULL) {
1445
        if (num != NULL) {
1446
            *num = 0;
1447
        }
1448
        return 0x1002;
1449
    }
1450
    if (num == NULL) {
1451
        return 0;
1452
    }
1453
    *num = 0;
1454
    while (DfChunksInterpret(df, &ModelLoadTable) != 0) {
1455
        if (DfTopType() == DF_MODEL) {
1456
            *num = *num + 1;
1457
            DfPop(DF_MODEL, NULL);
1458
        }
1459
    }
1460
    DfClose(df);
1461
    return 0;
1462
}
1463
 
1464
// IDA: br_error __cdecl BrActorFileCount(char *filename, br_uint_16 *num)
1465
br_error BrActorFileCount(char* filename, br_uint_16* num) {
1466
    br_datafile* df;
1467
    LOG_TRACE("(\"%s\", %p)", filename, num);
1468
 
1469
    df = DfOpen(filename, 0, BRT_FLOAT);
1470
    if (df == NULL) {
1471
        if (num != NULL) {
1472
            *num = 0;
1473
        }
1474
        return 0x1002;
1475
    }
1476
    if (num == NULL) {
1477
        return 0;
1478
    }
1479
    *num = 0;
1480
    while (DfChunksInterpret(df, &ActorLoadTable) != 0) {
1481
        if (DfTopType() == DF_ACTOR) {
1482
            *num = *num + 1;
1483
            DfPop(DF_ACTOR, NULL);
1484
        }
1485
    }
1486
    DfClose(df);
1487
    return 0;
1488
}
1489
 
1490
// IDA: br_error __cdecl BrMaterialFileCount(char *filename, br_uint_16 *num)
1491
br_error BrMaterialFileCount(char* filename, br_uint_16* num) {
1492
    br_datafile* df;
1493
    LOG_TRACE("(\"%s\", %p)", filename, num);
1494
 
1495
    df = DfOpen(filename, 0, BRT_FLOAT);
1496
    if (df == NULL) {
1497
        if (num != NULL) {
1498
            *num = 0;
1499
        }
1500
        return 0x1002;
1501
    }
1502
    if (num == NULL) {
1503
        return 0;
1504
    }
1505
    *num = 0;
1506
    while (DfChunksInterpret(df, &MaterialLoadTable) != 0) {
1507
        if (DfTopType() == DF_MATERIAL) {
1508
            *num = *num + 1;
1509
            DfPop(DF_MATERIAL, NULL);
1510
        }
1511
    }
1512
    DfClose(df);
1513
    return 0;
1514
}