Rev 18 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | #include "brucetrk.h" |
| 2 | |||
| 20 | pmbaty | 3 | #include "brender/brender.h" |
| 1 | pmbaty | 4 | #include "errors.h" |
| 5 | #include "globvars.h" |
||
| 6 | #include "globvrbm.h" |
||
| 7 | #include "harness/trace.h" |
||
| 8 | #include "init.h" |
||
| 9 | #include "pd/sys.h" |
||
| 10 | #include "utility.h" |
||
| 11 | #include "world.h" |
||
| 12 | #include <math.h> |
||
| 13 | #include <stdlib.h> |
||
| 14 | #include <string.h> |
||
| 15 | |||
| 16 | br_actor* gMr_blendy; |
||
| 17 | int gDefault_blend_pc; |
||
| 18 | |||
| 19 | // IDA: void __usercall AllocateActorMatrix(tTrack_spec *pTrack_spec@<EAX>, br_actor ****pDst@<EDX>) |
||
| 20 | void AllocateActorMatrix(tTrack_spec* pTrack_spec, br_actor**** pDst) { |
||
| 21 | tU16 z; |
||
| 22 | LOG_TRACE("(%p, %p)", pTrack_spec, pDst); |
||
| 23 | |||
| 24 | *pDst = BrMemAllocate(sizeof(br_actor***) * pTrack_spec->ncolumns_z, kMem_columns_z); |
||
| 25 | for (z = 0; z < pTrack_spec->ncolumns_z; z++) { |
||
| 26 | (*pDst)[z] = BrMemAllocate(sizeof(br_actor**) * pTrack_spec->ncolumns_x, kMem_columns_x); |
||
| 27 | memset((*pDst)[z], 0, sizeof(br_actor**) * pTrack_spec->ncolumns_x); |
||
| 28 | } |
||
| 29 | } |
||
| 30 | |||
| 31 | // IDA: void __usercall DisposeActorMatrix(tTrack_spec *pTrack_spec@<EAX>, br_actor ****pVictim@<EDX>, int pRemove_act_mod@<EBX>) |
||
| 32 | void DisposeActorMatrix(tTrack_spec* pTrack_spec, br_actor**** pVictim, int pRemove_act_mod) { |
||
| 33 | tU16 z; |
||
| 34 | tU16 x; |
||
| 35 | LOG_TRACE("(%p, %p, %d)", pTrack_spec, pVictim, pRemove_act_mod); |
||
| 36 | |||
| 37 | if (*pVictim != NULL) { |
||
| 38 | for (z = 0; z != pTrack_spec->ncolumns_z; z++) { |
||
| 39 | if (pRemove_act_mod != 0) { |
||
| 40 | for (x = 0; x != pTrack_spec->ncolumns_x; x++) { |
||
| 41 | if ((*pVictim)[z][x] != NULL && (*pVictim)[z][x]->model != NULL) { |
||
| 42 | BrModelRemove((*pVictim)[z][x]->model); |
||
| 43 | BrModelFree((*pVictim)[z][x]->model); |
||
| 44 | } |
||
| 45 | } |
||
| 46 | } |
||
| 47 | BrMemFree((*pVictim)[z]); |
||
| 48 | } |
||
| 49 | BrMemFree(*pVictim); |
||
| 50 | } |
||
| 51 | } |
||
| 52 | |||
| 53 | // IDA: void __usercall DisposeColumns(tTrack_spec *pTrack_spec@<EAX>) |
||
| 54 | void DisposeColumns(tTrack_spec* pTrack_spec) { |
||
| 55 | LOG_TRACE("(%p)", pTrack_spec); |
||
| 56 | |||
| 57 | DisposeActorMatrix(pTrack_spec, &pTrack_spec->columns, 0); |
||
| 58 | DisposeActorMatrix(pTrack_spec, &pTrack_spec->lollipops, 0); |
||
| 59 | if (gAusterity_mode == 0) { |
||
| 60 | DisposeActorMatrix(pTrack_spec, &pTrack_spec->blends, 1); |
||
| 61 | } |
||
| 62 | if (pTrack_spec->non_car_list != NULL && (0 < pTrack_spec->ampersand_digits)) { |
||
| 63 | BrMemFree(pTrack_spec->non_car_list); |
||
| 64 | } |
||
| 65 | } |
||
| 66 | |||
| 67 | // IDA: void __usercall XZToColumnXZ(tU8 *pColumn_x@<EAX>, tU8 *pColumn_z@<EDX>, br_scalar pX, br_scalar pZ, tTrack_spec *pTrack_spec) |
||
| 68 | void XZToColumnXZ(tU8* pColumn_x, tU8* pColumn_z, br_scalar pX, br_scalar pZ, tTrack_spec* pTrack_spec) { |
||
| 69 | br_scalar x; |
||
| 70 | br_scalar z; |
||
| 71 | LOG_TRACE("(%p, %p, %f, %f, %p)", pColumn_x, pColumn_z, pX, pZ, pTrack_spec); |
||
| 72 | |||
| 73 | x = (pX - pTrack_spec->origin_x) / pTrack_spec->column_size_x; |
||
| 74 | z = (pZ - pTrack_spec->origin_z) / pTrack_spec->column_size_z; |
||
| 75 | if (x < 0.0f) { |
||
| 76 | x = 0.0f; |
||
| 77 | } |
||
| 78 | if (x >= pTrack_spec->ncolumns_x) { |
||
| 79 | x = pTrack_spec->ncolumns_x - 1.0f; |
||
| 80 | } |
||
| 81 | if (z < 0.0f) { |
||
| 82 | z = 0.0f; |
||
| 83 | } |
||
| 84 | if (z >= pTrack_spec->ncolumns_z) { |
||
| 85 | z = pTrack_spec->ncolumns_z - 1.0f; |
||
| 86 | } |
||
| 87 | *pColumn_x = (tU8) x; // Pierre-Marie Baty -- added type cast |
||
| 88 | *pColumn_z = (tU8) z; // Pierre-Marie Baty -- added type cast |
||
| 89 | } |
||
| 90 | |||
| 91 | // IDA: void __usercall StripBlendedFaces(br_actor *pActor@<EAX>, br_model *pModel@<EDX>) |
||
| 92 | void StripBlendedFaces(br_actor* pActor, br_model* pModel) { |
||
| 93 | int i; |
||
| 94 | br_face* face; |
||
| 95 | int changed_one; |
||
| 96 | //char s[256]; // Pierre-Marie Baty -- unused variable |
||
| 97 | static tU16 nfaces_allocated; |
||
| 98 | LOG_TRACE("(%p, %p)", pActor, pModel); |
||
| 99 | |||
| 100 | changed_one = 0; |
||
| 101 | |||
| 102 | for (i = 0; i < pModel->nfaces; i++) { |
||
| 103 | face = &pModel->faces[i]; |
||
| 104 | if (face->material != NULL && face->material->identifier != NULL && ((face->material->identifier[0] == '!' && face->material->identifier[1] != '!' && gDefault_blend_pc != 0) || face->material->identifier[1] == '\\')) { |
||
| 105 | if (gMr_blendy == NULL) { |
||
| 106 | gMr_blendy = BrActorAllocate(BR_ACTOR_MODEL, NULL); |
||
| 107 | gMr_blendy->render_style = BR_RSTYLE_NONE; |
||
| 108 | gMr_blendy->model = BrModelAllocate(NULL, pModel->nvertices, pModel->nfaces); |
||
| 109 | nfaces_allocated = pModel->nfaces; |
||
| 110 | gMr_blendy->model->nfaces = 0; |
||
| 111 | gMr_blendy->model->flags |= BR_MODF_UPDATEABLE; |
||
| 112 | memcpy(gMr_blendy->model->vertices, pModel->vertices, pModel->nvertices * sizeof(br_vertex)); |
||
| 113 | } |
||
| 114 | if (!AlreadyBlended(face->material)) { |
||
| 115 | if (face->material->identifier[1] == '\\') { |
||
| 116 | if (face->material->identifier[2] == '2') { |
||
| 117 | BlendifyMaterial(face->material, 25); |
||
| 118 | } else if (face->material->identifier[2] == '7') { |
||
| 119 | BlendifyMaterial(face->material, 75); |
||
| 120 | } else { |
||
| 121 | BlendifyMaterial(face->material, 50); |
||
| 122 | } |
||
| 123 | } else { |
||
| 124 | BlendifyMaterial(face->material, gDefault_blend_pc); |
||
| 125 | } |
||
| 126 | BrMaterialUpdate(face->material, BR_MATU_ALL); |
||
| 127 | } |
||
| 128 | if (nfaces_allocated <= gMr_blendy->model->nfaces) { |
||
| 129 | PDFatalError("Perfectly understandable error by Batwick, thank you very much Bruce."); |
||
| 130 | } |
||
| 131 | memcpy(&gMr_blendy->model->faces[gMr_blendy->model->nfaces], face, sizeof(br_face)); |
||
| 132 | gMr_blendy->model->nfaces++; |
||
| 133 | if (i < (pModel->nfaces - 1)) { |
||
| 134 | memmove(&pModel->faces[i], &pModel->faces[i + 1], (pModel->nfaces - i - 1) * sizeof(br_face)); |
||
| 135 | } |
||
| 136 | pModel->nfaces--; |
||
| 137 | changed_one = 1; |
||
| 138 | i--; |
||
| 139 | } |
||
| 140 | } |
||
| 141 | if (changed_one) { |
||
| 142 | if (pModel->nfaces != 0) { |
||
| 143 | BrModelUpdate(pModel, BR_MODU_ALL); |
||
| 144 | } else { |
||
| 145 | pActor->model = NULL; |
||
| 146 | pActor->type = BR_ACTOR_NONE; |
||
| 147 | } |
||
| 148 | } |
||
| 149 | } |
||
| 150 | |||
| 151 | // IDA: br_uint_32 __cdecl FindNonCarsCB(br_actor *pActor, tTrack_spec *pTrack_spec) |
||
| 20 | pmbaty | 152 | intptr_t FindNonCarsCB(br_actor* pActor, tTrack_spec* pTrack_spec) { |
| 1 | pmbaty | 153 | int i; |
| 154 | br_scalar r1; |
||
| 155 | br_scalar r2; |
||
| 156 | br_scalar r3; |
||
| 157 | LOG_TRACE("(%p, %p)", pActor, pTrack_spec); |
||
| 158 | |||
| 159 | if (pActor->identifier != NULL && pActor->identifier[0] == '&' && pActor->identifier[1] >= '0' && pActor->identifier[1] <= '9') { |
||
| 160 | i = (pActor->identifier[4] - '0') * 1000 + (pActor->identifier[5] - '0') * 100 + (pActor->identifier[6] - '0') * 10 + (pActor->identifier[7] - '0'); |
||
| 161 | if (i < 0 || pTrack_spec->ampersand_digits <= i) { |
||
| 162 | return 1; |
||
| 163 | } |
||
| 164 | r1 = BR_SQR3(pActor->t.t.mat.m[0][0], pActor->t.t.mat.m[0][1], pActor->t.t.mat.m[0][2]); |
||
| 165 | r2 = BR_SQR3(pActor->t.t.mat.m[1][0], pActor->t.t.mat.m[1][1], pActor->t.t.mat.m[1][2]); |
||
| 166 | r3 = BR_SQR3(pActor->t.t.mat.m[2][0], pActor->t.t.mat.m[2][1], pActor->t.t.mat.m[2][2]); |
||
| 167 | if (r1 < .999f || r2 < .999f || r3 < .999f) { |
||
| 168 | dr_dprintf("non car was scaled down %s", pActor->identifier); |
||
| 169 | pActor->t.t.translate.t.v[0] += 2000.f; |
||
| 170 | } |
||
| 171 | if (r1 > 1.001f || r2 > 1.001f || r3 > 1.001f) { |
||
| 172 | r1 = 1.f / sqrtf(r1); |
||
| 173 | r2 = 1.f / sqrtf(r2); |
||
| 174 | r3 = 1.f / sqrtf(r3); |
||
| 175 | pActor->t.t.mat.m[0][0] *= r1; |
||
| 176 | pActor->t.t.mat.m[0][1] *= r1; |
||
| 177 | pActor->t.t.mat.m[0][2] *= r1; |
||
| 178 | pActor->t.t.mat.m[1][0] *= r2; |
||
| 179 | pActor->t.t.mat.m[1][1] *= r2; |
||
| 180 | pActor->t.t.mat.m[1][2] *= r2; |
||
| 181 | pActor->t.t.mat.m[2][0] *= r3; |
||
| 182 | pActor->t.t.mat.m[2][1] *= r3; |
||
| 183 | pActor->t.t.mat.m[2][2] *= r3; |
||
| 184 | dr_dprintf("non car was scaled up %s", pActor->identifier); |
||
| 185 | } |
||
| 186 | pTrack_spec->non_car_list[i] = pActor; |
||
| 187 | pActor->type_data = NULL; |
||
| 188 | return 0; |
||
| 189 | } else { |
||
| 190 | if (pActor->model != NULL && !gAusterity_mode && pActor->identifier != NULL && pActor->identifier[0] != '&') { |
||
| 191 | StripBlendedFaces(pActor, pActor->model); |
||
| 192 | } |
||
| 193 | return BrActorEnum(pActor, (br_actor_enum_cbfn*)FindNonCarsCB, pTrack_spec); |
||
| 194 | } |
||
| 195 | } |
||
| 196 | |||
| 197 | // IDA: br_uint_32 __cdecl ProcessModelsCB(br_actor *pActor, tTrack_spec *pTrack_spec) |
||
| 20 | pmbaty | 198 | intptr_t ProcessModelsCB(br_actor* pActor, tTrack_spec* pTrack_spec) { |
| 1 | pmbaty | 199 | unsigned int x; |
| 200 | unsigned int z; |
||
| 201 | int group; |
||
| 202 | LOG_TRACE("(%p, %p)", pActor, pTrack_spec); |
||
| 203 | |||
| 204 | if (sscanf(pActor->identifier, "%u%u", &x, &z) == 2 && pTrack_spec->ncolumns_x > x && pTrack_spec->ncolumns_z > z) { |
||
| 205 | pActor->material = gDefault_track_material; |
||
| 206 | pTrack_spec->columns[z][x] = pActor; |
||
| 207 | gMr_blendy = NULL; |
||
| 208 | if (pActor->model && !gAusterity_mode) { |
||
| 209 | StripBlendedFaces(pActor, pActor->model); |
||
| 210 | } |
||
| 211 | BrActorEnum(pActor, (br_actor_enum_cbfn*)FindNonCarsCB, pTrack_spec); |
||
| 212 | if (gMr_blendy) { |
||
| 213 | BrActorAdd(pActor, gMr_blendy); |
||
| 214 | BrModelAdd(gMr_blendy->model); |
||
| 20 | pmbaty | 215 | for (group = 0; V11MODEL(gMr_blendy->model)->ngroups > group; ++group) { |
| 216 | V11MODEL(gMr_blendy->model)->groups[group].face_colours_material = gMr_blendy->model->faces[*V11MODEL(gMr_blendy->model)->groups[group].face_user].material; |
||
| 1 | pmbaty | 217 | } |
| 218 | gMr_blendy->model->flags &= ~BR_MODF_UPDATEABLE; |
||
| 219 | DodgyModelUpdate(gMr_blendy->model); |
||
| 220 | pTrack_spec->blends[z][x] = gMr_blendy; |
||
| 221 | } |
||
| 222 | } else if (*pActor->identifier == '%' && sscanf((const char*)pActor->identifier + 1, "%u%u", &x, &z) == 2 && pTrack_spec->ncolumns_x > x && pTrack_spec->ncolumns_z > z) { |
||
| 223 | pTrack_spec->lollipops[z][x] = pActor; |
||
| 224 | } else { |
||
| 225 | BrActorEnum(pActor, (br_actor_enum_cbfn*)ProcessModelsCB, pTrack_spec); |
||
| 226 | } |
||
| 227 | return 0; |
||
| 228 | } |
||
| 229 | |||
| 230 | // IDA: void __usercall ProcessModels(tTrack_spec *pTrack_spec@<EAX>) |
||
| 231 | void ProcessModels(tTrack_spec* pTrack_spec) { |
||
| 232 | LOG_TRACE("(%p)", pTrack_spec); |
||
| 233 | |||
| 234 | BrActorEnum(pTrack_spec->the_actor, (br_actor_enum_cbfn*)ProcessModelsCB, pTrack_spec); |
||
| 235 | } |
||
| 236 | |||
| 237 | // IDA: void __usercall ExtractColumns(tTrack_spec *pTrack_spec@<EAX>) |
||
| 238 | void ExtractColumns(tTrack_spec* pTrack_spec) { |
||
| 239 | unsigned int x; |
||
| 240 | unsigned int z; |
||
| 241 | int ad; |
||
| 242 | int unsplit; |
||
| 243 | //float e; // Pierre-Marie Baty -- unused variable |
||
| 244 | br_scalar extra_room; |
||
| 245 | br_bounds bounds; |
||
| 246 | LOG_TRACE("(%p)", pTrack_spec); |
||
| 247 | |||
| 248 | unsplit = 0; |
||
| 249 | switch (sscanf(pTrack_spec->the_actor->identifier, "%u%u%f%d", &x, &z, &extra_room, &ad)) { |
||
| 250 | case 3: |
||
| 251 | BrFailure( |
||
| 252 | "Attempt to extract columns from invalid track\n" |
||
| 253 | "(It might have been produced by an ancient preproc.\n" |
||
| 254 | "This is no longer supported.\n"); |
||
| 255 | break; |
||
| 256 | |||
| 257 | case 4: |
||
| 258 | pTrack_spec->ampersand_digits = ad; |
||
| 259 | break; |
||
| 260 | |||
| 261 | default: |
||
| 262 | unsplit = 1; |
||
| 263 | x = 1; |
||
| 264 | z = 1; |
||
| 265 | extra_room = 0.0; |
||
| 266 | pTrack_spec->ampersand_digits = 0; |
||
| 267 | } |
||
| 268 | pTrack_spec->ncolumns_x = x; |
||
| 269 | pTrack_spec->ncolumns_z = z; |
||
| 270 | |||
| 271 | BrActorToBounds(&bounds, pTrack_spec->the_actor); |
||
| 20 | pmbaty | 272 | pTrack_spec->column_size_x = (br_scalar) (bounds.max.v[0] - bounds.min.v[0] + extra_room * (br_scalar) 2.0) / (double)pTrack_spec->ncolumns_x; // Pierre-Marie Baty -- added type casts |
| 273 | pTrack_spec->column_size_z = (br_scalar) (bounds.max.v[2] - bounds.min.v[2] + extra_room * (br_scalar) 2.0) / (double)pTrack_spec->ncolumns_z; // Pierre-Marie Baty -- added type casts |
||
| 1 | pmbaty | 274 | pTrack_spec->origin_x = bounds.min.v[0] - extra_room; |
| 275 | pTrack_spec->origin_z = bounds.min.v[2] - extra_room; |
||
| 276 | AllocateActorMatrix(pTrack_spec, &pTrack_spec->columns); |
||
| 277 | AllocateActorMatrix(pTrack_spec, &pTrack_spec->lollipops); |
||
| 278 | AllocateActorMatrix(pTrack_spec, &pTrack_spec->blends); |
||
| 279 | if (pTrack_spec->ampersand_digits <= 0) { |
||
| 280 | pTrack_spec->non_car_list = NULL; |
||
| 281 | } else { |
||
| 282 | pTrack_spec->non_car_list = BrMemAllocate(sizeof(br_actor*) * pTrack_spec->ampersand_digits, kMem_non_car_list); |
||
| 283 | } |
||
| 284 | if (unsplit) { |
||
| 285 | **pTrack_spec->columns = pTrack_spec->the_actor; |
||
| 286 | } else { |
||
| 287 | ProcessModels(pTrack_spec); |
||
| 288 | } |
||
| 289 | } |
||
| 290 | |||
| 291 | // IDA: void __usercall LollipopizeActor4(br_actor *pActor@<EAX>, br_matrix34 *pRef_to_world@<EDX>, br_actor *pCamera@<EBX>) |
||
| 292 | void LollipopizeActor4(br_actor* pActor, br_matrix34* pRef_to_world, br_actor* pCamera) { |
||
| 293 | LOG_TRACE("(%p, %p, %p)", pActor, pRef_to_world, pCamera); |
||
| 294 | |||
| 295 | pActor->t.t.mat.m[1][0] = 0.0; |
||
| 296 | pActor->t.t.mat.m[1][1] = 1.0; |
||
| 297 | pActor->t.t.mat.m[1][2] = 0.0; |
||
| 298 | pActor->t.t.mat.m[2][0] = pRef_to_world->m[2][0]; |
||
| 299 | pActor->t.t.mat.m[2][1] = pRef_to_world->m[2][1]; |
||
| 300 | pActor->t.t.mat.m[2][2] = pRef_to_world->m[2][2]; |
||
| 301 | pActor->t.t.mat.m[0][0] = pActor->t.t.mat.m[1][1] * pActor->t.t.mat.m[2][2] |
||
| 302 | - pActor->t.t.mat.m[1][2] * pActor->t.t.mat.m[2][1]; |
||
| 303 | pActor->t.t.mat.m[0][1] = pActor->t.t.mat.m[1][2] * pActor->t.t.mat.m[2][0] |
||
| 304 | - pActor->t.t.mat.m[1][0] * pActor->t.t.mat.m[2][2]; |
||
| 305 | pActor->t.t.mat.m[0][2] = pActor->t.t.mat.m[2][1] * pActor->t.t.mat.m[1][0] |
||
| 306 | - pActor->t.t.mat.m[1][1] * pActor->t.t.mat.m[2][0]; |
||
| 307 | } |
||
| 308 | |||
| 309 | // IDA: br_uint_32 __cdecl LollipopizeChildren(br_actor *pActor, void *pArg) |
||
| 20 | pmbaty | 310 | intptr_t LollipopizeChildren(br_actor* pActor, void* pArg) { |
| 1 | pmbaty | 311 | tMatrix_and_actor* maa; |
| 312 | LOG_TRACE("(%p, %p)", pActor, pArg); |
||
| 313 | |||
| 314 | maa = pArg; |
||
| 315 | LollipopizeActor4(pActor, maa->m, maa->a); |
||
| 316 | return 0; |
||
| 317 | } |
||
| 318 | |||
| 319 | // IDA: void __usercall DrawColumns(int pDraw_blends@<EAX>, tTrack_spec *pTrack_spec@<EDX>, int pMin_x@<EBX>, int pMax_x@<ECX>, int pMin_z, int pMax_z, br_matrix34 *pCamera_to_world) |
||
| 320 | void DrawColumns(int pDraw_blends, tTrack_spec* pTrack_spec, int pMin_x, int pMax_x, int pMin_z, int pMax_z, br_matrix34* pCamera_to_world) { |
||
| 321 | tU8 column_x; |
||
| 322 | tU8 column_z; |
||
| 323 | tU8 column_x2; |
||
| 324 | tU8 column_z2; |
||
| 325 | tMatrix_and_actor maa; |
||
| 326 | br_actor* blended_polys; |
||
| 327 | LOG_TRACE("(%d, %p, %d, %d, %d, %d, %p)", pDraw_blends, pTrack_spec, pMin_x, pMax_x, pMin_z, pMax_z, pCamera_to_world); |
||
| 328 | |||
| 329 | maa.m = pCamera_to_world; |
||
| 330 | if (fabs(pCamera_to_world->m[2][2]) >= fabs(pCamera_to_world->m[2][0])) { |
||
| 331 | for (column_z = pMin_z; column_z <= pMax_z; ++column_z) { |
||
| 332 | for (column_x = pMin_x; column_x <= pMax_x; ++column_x) { |
||
| 333 | if (pCamera_to_world->m[2][0] <= 0.0) { |
||
| 334 | column_x2 = pMin_x + pMax_x - column_x; |
||
| 335 | } else { |
||
| 336 | column_x2 = column_x; |
||
| 337 | } |
||
| 338 | if (pCamera_to_world->m[2][2] <= 0.0) { |
||
| 339 | column_z2 = pMax_z + pMin_z - column_z; |
||
| 340 | } else { |
||
| 341 | column_z2 = column_z; |
||
| 342 | } |
||
| 343 | if (pDraw_blends) { |
||
| 344 | blended_polys = pTrack_spec->blends[column_z2][column_x2]; |
||
| 345 | if (blended_polys) { |
||
| 346 | blended_polys->render_style = BR_RSTYLE_FACES; |
||
| 347 | BrZbSceneRenderAdd(blended_polys); |
||
| 348 | blended_polys->render_style = BR_RSTYLE_NONE; |
||
| 349 | } |
||
| 350 | } else { |
||
| 351 | if (pTrack_spec->columns[column_z2][column_x2]) { |
||
| 352 | BrZbSceneRenderAdd(pTrack_spec->columns[column_z2][column_x2]); |
||
| 353 | } |
||
| 354 | if (pTrack_spec->lollipops[column_z2][column_x2]) { |
||
| 355 | maa.a = pTrack_spec->lollipops[column_z2][column_x2]; |
||
| 356 | BrActorEnum(pTrack_spec->lollipops[column_z2][column_x2], LollipopizeChildren, &maa); |
||
| 357 | BrZbSceneRenderAdd(pTrack_spec->lollipops[column_z2][column_x2]); |
||
| 358 | } |
||
| 359 | } |
||
| 360 | } |
||
| 361 | } |
||
| 362 | } else { |
||
| 363 | for (column_x = pMin_x; column_x <= pMax_x; ++column_x) { |
||
| 364 | for (column_z = pMin_z; column_z <= pMax_z; ++column_z) { |
||
| 365 | if (pCamera_to_world->m[2][0] <= 0.0) { |
||
| 366 | column_x2 = pMin_x + pMax_x - column_x; |
||
| 367 | } else { |
||
| 368 | column_x2 = column_x; |
||
| 369 | } |
||
| 370 | if (pCamera_to_world->m[2][2] <= 0.0) { |
||
| 371 | column_z2 = pMax_z + pMin_z - column_z; |
||
| 372 | } else { |
||
| 373 | column_z2 = column_z; |
||
| 374 | } |
||
| 375 | if (pDraw_blends) { |
||
| 376 | blended_polys = pTrack_spec->blends[column_z2][column_x2]; |
||
| 377 | if (blended_polys) { |
||
| 20 | pmbaty | 378 | blended_polys->render_style = 4; |
| 1 | pmbaty | 379 | BrZbSceneRenderAdd(blended_polys); |
| 20 | pmbaty | 380 | blended_polys->render_style = 1; |
| 1 | pmbaty | 381 | } |
| 382 | } else { |
||
| 383 | if (pTrack_spec->columns[column_z2][column_x2]) { |
||
| 384 | BrZbSceneRenderAdd(pTrack_spec->columns[column_z2][column_x2]); |
||
| 385 | } |
||
| 386 | if (pTrack_spec->lollipops[column_z2][column_x2]) { |
||
| 387 | maa.a = pTrack_spec->lollipops[column_z2][column_x2]; |
||
| 388 | BrActorEnum(pTrack_spec->lollipops[column_z2][column_x2], LollipopizeChildren, &maa); |
||
| 389 | BrZbSceneRenderAdd(pTrack_spec->lollipops[column_z2][column_x2]); |
||
| 390 | } |
||
| 391 | } |
||
| 392 | } |
||
| 393 | } |
||
| 394 | } |
||
| 395 | } |
||
| 396 | |||
| 397 | // IDA: void __usercall RenderTrack(br_actor *pWorld@<EAX>, tTrack_spec *pTrack_spec@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>, int pRender_blends) |
||
| 398 | void RenderTrack(br_actor* pWorld, tTrack_spec* pTrack_spec, br_actor* pCamera, br_matrix34* pCamera_to_world, int pRender_blends) { |
||
| 399 | static tU8 column_x; |
||
| 400 | static tU8 column_z; |
||
| 401 | static tU8 min_x; |
||
| 402 | static tU8 max_x; |
||
| 403 | static tU8 min_z; |
||
| 404 | static tU8 max_z; |
||
| 405 | static br_vector3 edge_before; |
||
| 406 | static br_vector3 edge_after; |
||
| 407 | static br_camera* camera; |
||
| 408 | static br_scalar tan_fov_ish; |
||
| 409 | static br_actor* result; |
||
| 410 | LOG_TRACE("(%p, %p, %p, %p, %d)", pWorld, pTrack_spec, pCamera, pCamera_to_world, pRender_blends); |
||
| 411 | |||
| 412 | if (pTrack_spec->columns != NULL) { |
||
| 413 | if (pRender_blends) { |
||
| 414 | DrawColumns(1, pTrack_spec, min_x, max_x, min_z, max_z, pCamera_to_world); |
||
| 415 | } else { |
||
| 416 | camera = (br_camera*)pCamera->type_data; |
||
| 417 | XZToColumnXZ(&column_x, &column_z, pCamera_to_world->m[3][0], pCamera_to_world->m[3][2], pTrack_spec); |
||
| 418 | min_x = column_x; |
||
| 419 | max_x = column_x; |
||
| 420 | min_z = column_z; |
||
| 421 | max_z = column_z; |
||
| 422 | tan_fov_ish = sinf(BrAngleToRadian(camera->field_of_view / 2)) / cosf(BrAngleToRadian(camera->field_of_view / 2)); |
||
| 423 | edge_after.v[0] = camera->aspect * tan_fov_ish; |
||
| 424 | edge_after.v[1] = tan_fov_ish; |
||
| 425 | edge_after.v[2] = -1.0; |
||
| 426 | edge_before.v[0] = camera->yon_z * gYon_factor * edge_after.v[0]; |
||
| 427 | edge_before.v[1] = camera->yon_z * gYon_factor * tan_fov_ish; |
||
| 428 | edge_before.v[2] = camera->yon_z * gYon_factor * (br_scalar) -1.0; // Pierre-Marie Baty -- added type cast |
||
| 429 | BrMatrix34ApplyV(&edge_after, &edge_before, pCamera_to_world); |
||
| 430 | XZToColumnXZ(&column_x, &column_z, pCamera_to_world->m[3][0] + edge_after.v[0], pCamera_to_world->m[3][2] + edge_after.v[2], pTrack_spec); |
||
| 431 | if (column_x < min_x) { |
||
| 432 | min_x = column_x; |
||
| 433 | } else if (column_x > max_x) { |
||
| 434 | max_x = column_x; |
||
| 435 | } |
||
| 436 | if (column_z < min_z) { |
||
| 437 | min_z = column_z; |
||
| 438 | } else if (column_z > max_z) { |
||
| 439 | max_z = column_z; |
||
| 440 | } |
||
| 441 | edge_before.v[0] = -edge_before.v[0]; |
||
| 442 | BrMatrix34ApplyV(&edge_after, &edge_before, pCamera_to_world); |
||
| 443 | XZToColumnXZ(&column_x, &column_z, pCamera_to_world->m[3][0] + edge_after.v[0], pCamera_to_world->m[3][2] + edge_after.v[2], pTrack_spec); |
||
| 444 | if (column_x < min_x) { |
||
| 445 | min_x = column_x; |
||
| 446 | } else if (column_x > max_x) { |
||
| 447 | max_x = column_x; |
||
| 448 | } |
||
| 449 | if (column_z >= min_z) { |
||
| 450 | if (column_z > max_z) { |
||
| 451 | max_z = column_z; |
||
| 452 | } |
||
| 453 | } else { |
||
| 454 | min_z = column_z; |
||
| 455 | } |
||
| 456 | edge_before.v[1] = -edge_before.v[1]; |
||
| 457 | BrMatrix34ApplyV(&edge_after, &edge_before, pCamera_to_world); |
||
| 458 | XZToColumnXZ(&column_x, &column_z, pCamera_to_world->m[3][0] + edge_after.v[0], pCamera_to_world->m[3][2] + edge_after.v[2], pTrack_spec); |
||
| 459 | if (column_x < min_x) { |
||
| 460 | min_x = column_x; |
||
| 461 | } else if (column_x > max_x) { |
||
| 462 | max_x = column_x; |
||
| 463 | } |
||
| 464 | if (column_z < min_z) { |
||
| 465 | min_z = column_z; |
||
| 466 | } else if (column_z > max_z) { |
||
| 467 | max_z = column_z; |
||
| 468 | } |
||
| 469 | edge_before.v[0] = -edge_before.v[0]; |
||
| 470 | BrMatrix34ApplyV(&edge_after, &edge_before, pCamera_to_world); |
||
| 471 | XZToColumnXZ(&column_x, &column_z, pCamera_to_world->m[3][0] + edge_after.v[0], pCamera_to_world->m[3][2] + edge_after.v[2], pTrack_spec); |
||
| 472 | if (column_x < min_x) { |
||
| 473 | min_x = column_x; |
||
| 474 | } else if (column_x > max_x) { |
||
| 475 | max_x = column_x; |
||
| 476 | } |
||
| 477 | if (column_z < min_z) { |
||
| 478 | min_z = column_z; |
||
| 479 | } else if (column_z > max_z) { |
||
| 480 | max_z = column_z; |
||
| 481 | } |
||
| 482 | if (min_x != 0) { |
||
| 483 | min_x--; |
||
| 484 | } |
||
| 485 | if (pTrack_spec->ncolumns_x - 1 > max_x) { |
||
| 486 | max_x++; |
||
| 487 | } |
||
| 488 | if (min_z != 0) { |
||
| 489 | min_z--; |
||
| 490 | } |
||
| 491 | if (pTrack_spec->ncolumns_z - 1 > max_z) { |
||
| 492 | max_z++; |
||
| 493 | } |
||
| 494 | DrawColumns(0, pTrack_spec, min_x, max_x, min_z, max_z, pCamera_to_world); |
||
| 495 | } |
||
| 496 | } else { |
||
| 497 | BrZbSceneRenderAdd(pWorld); |
||
| 498 | } |
||
| 499 | } |
||
| 500 | |||
| 501 | // IDA: br_scalar __cdecl GetYonFactor() |
||
| 502 | br_scalar GetYonFactor(void) { |
||
| 503 | |||
| 504 | return gYon_factor; |
||
| 505 | } |
||
| 506 | |||
| 507 | // IDA: void __cdecl SetYonFactor(br_scalar pNew) |
||
| 508 | void SetYonFactor(br_scalar pNew) { |
||
| 509 | |||
| 510 | gYon_factor = pNew; |
||
| 511 | } |