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