Skip to content

Commit 42178c9

Browse files
committed
reflect.c: ABTEST=REFL measures the reflection options within one run
All three switch off in the A/B off slices; the cube map far plane goes back to the game's own value there. Measured at 3024x1898 (Quick Race, highest clock): 0.00 +- 0.06 Mcycles/frame, i.e. the options cost nothing measurable.
1 parent 53283b5 commit 42178c9

1 file changed

Lines changed: 17 additions & 9 deletions

File tree

‎runtime/reflect.c‎

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ uint32_t call_guest(CPU *c, uint32_t fn, int nargs, const uint32_t *args); /*
6969
static int g_init, g_sky, g_lights, g_detail;
7070
static unsigned long g_n_sky[2], g_n_lod, g_n_car, g_n_lights;
7171
static int g_lights_here;
72+
static float g_cube_far0 = -1.f; /* the game's cube map far plane (64 m) */
73+
74+
/* ABTEST=REFL (metal.m IN-RUN A/B): all three off in the measurement's off slices */
75+
static int ab_on(void){ int metal_abt_off(const char *); return !metal_abt_off("REFL"); }
76+
#define SKY (g_sky && ab_on())
77+
#define LIGHTS (g_lights && ab_on())
78+
#define DETAIL (g_detail && ab_on())
7279

7380
static int on(const char *name){
7481
const char *e = getenv(name);
@@ -93,7 +100,7 @@ int refl_hook(CPU *c, uint32_t ip){
93100
switch (ip){
94101
case H_ROAD_SCENERY: case H_MIRROR_SCENERY:
95102
refl_init();
96-
if (g_sky && c->esi){
103+
if (SKY && c->esi){
97104
uint32_t a[1] = { c->esi }, pool = MR32(SKY_POOL);
98105
call_guest(c, FN_SKY, 1, a);
99106
/* The road reflection draws the scenery mirrored in z (0x5d67b9 negates
@@ -109,7 +116,7 @@ int refl_hook(CPU *c, uint32_t ip){
109116
/* The road reflection takes the main views' path (edx 1-3 draw the sky).
110117
* The main views' sky (scale 1) fits inside their 10 km far plane; the
111118
* mirror's far plane is 192 m, so its sky is scaled to fit inside its own. */
112-
if (g_sky && (c->edx == 3u || c->edx == 4u)){
119+
if (SKY && (c->edx == 3u || c->edx == 4u)){
113120
uint32_t v = MR32(c->ebp + 8u), cam = v ? MR32(v + 0x40u) : 0u;
114121
float far = cam ? MRF32(cam + 0xc0u) : 0.f, k = far / 10400.f;
115122
if (k > 0.f) ST(0) = (double)(k < 1.f ? k : 1.f);
@@ -118,14 +125,15 @@ int refl_hook(CPU *c, uint32_t ip){
118125
return 1;
119126
case H_SCENERY_LOD:
120127
refl_init();
121-
if (g_detail && (c->ebx & 0x1820u)){
122-
static int far_set;
123-
if (!far_set){ far_set = 1; MRF32(CUBE_FAR) = 10000.f; }
124-
c->ebx &= ~0x1820u; g_n_lod++;
128+
if (g_detail){
129+
if (g_cube_far0 < 0.f) g_cube_far0 = MRF32(CUBE_FAR);
130+
float want = DETAIL ? 10000.f : g_cube_far0;
131+
if (MRF32(CUBE_FAR) != want) MRF32(CUBE_FAR) = want;
125132
}
133+
if (DETAIL && (c->ebx & 0x1820u)){ c->ebx &= ~0x1820u; g_n_lod++; }
126134
return 1;
127135
case H_CAR_LOD: case H_CAR_LOD2:
128-
if (g_detail){
136+
if (DETAIL){
129137
uint32_t v = MR32(c->ebp + 8u);
130138
if (v && refl_view(MR32(v + 4u))){
131139
if (ip == H_CAR_LOD){ c->ecx = 0; c->edx = 0; }
@@ -141,14 +149,14 @@ int refl_hook(CPU *c, uint32_t ip){
141149
/* ---- car lights in the road reflection (tools/gen_v2.sh OVR) -------------- */
142150
void sub_006154a0(CPU *c){ /* cdecl (eView *view) */
143151
refl_init();
144-
if (g_lights && !g_lights_here){ POP32(c->eip); return; } /* drawn below instead */
152+
if (LIGHTS && !g_lights_here){ POP32(c->eip); return; } /* drawn below instead */
145153
sub_006154a0_orig(c);
146154
}
147155

148156
void sub_00494270(CPU *c){ /* cdecl (eView *view, int, int pass) */
149157
refl_init();
150158
uint32_t v = MR32(c->esp + 4u);
151-
if (g_lights && v && MR32(v + 4u) == 4u && MR32(c->esp + 12u) == 1u){
159+
if (LIGHTS && v && MR32(v + 4u) == 4u && MR32(c->esp + 12u) == 1u){
152160
g_lights_here = 1;
153161
PUSH32(v); PUSH32(MR32(c->esp + 4u));
154162
sub_006154a0_orig(c);

0 commit comments

Comments
 (0)