@@ -69,6 +69,13 @@ uint32_t call_guest(CPU *c, uint32_t fn, int nargs, const uint32_t *args); /*
6969static int g_init , g_sky , g_lights , g_detail ;
7070static unsigned long g_n_sky [2 ], g_n_lod , g_n_car , g_n_lights ;
7171static 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
7380static 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) -------------- */
142150void 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
148156void 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