Subversion Repositories Games.Carmageddon

Rev

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
}