Subversion Repositories Games.Carmageddon

Rev

Blame | Last modification | View Log | Download | RSS feed

  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. }
  1515.