@@ -28,37 +28,56 @@ void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver*
2828 iVar12_A = ((driver -> axisRotationX - driver -> angle ) + 0x800U & 0xfff ) - 0x800 ;
2929 if (iVar12_A != 0 )
3030 {
31- #ifdef USE_60FPS
31+ // 30fps
32+ #ifndef USE_60FPS
33+
34+ // decrease by 1/8
35+ // val = val * 7/8
36+ iVar13 = iVar12_A >> 3 ;
37+
38+ // 60fps
39+ #else
40+
41+ // how to split division by 8,
42+ // into two separate frames, which is
43+ // exponentional at 30fps, but a hybrid
44+ // linear/exponential at 60fps
45+
3246 if (gGT -> timer & 1 )
3347 {
48+ // 1/16, half of 1/8
49+ iVar13 = iVar12_A >> 4 ;
50+ }
51+ else
52+ {
53+ // undo last frame's change,
54+ // undo 1/16 change, with 16/15
55+ iVar13 = (iVar12_A * 16 ) / 15 ;
56+
57+ // now take 1/8 of that
58+ iVar13 = iVar13 >> 3 ;
59+ }
60+
3461 #endif
3562
36- iVar13 = iVar12_A >> 3 ;
37- if (iVar13 == 0 )
38- {
39- iVar13 = 1 ;
40- }
63+ if (iVar13 == 0 )
64+ {
65+ iVar13 = 1 ;
66+ }
4167
42- // FPS_DOUBLE, not FPS_HALF, cause this happens
43- // once every 2 frames, that's how we solve
44- // the "iVar12_A" exponential problem
45- elapsedTimeDouble = gGT -> elapsedTimeMS * FPS_DOUBLE (2 );
68+ elapsedTimeDouble = gGT -> elapsedTimeMS * 2 ;
4669
47- if (iVar13 > elapsedTimeDouble )
48- iVar13 = elapsedTimeDouble ;
49-
50- if (iVar13 < - elapsedTimeDouble )
51- iVar13 = - elapsedTimeDouble ;
70+ if (iVar13 > elapsedTimeDouble )
71+ iVar13 = elapsedTimeDouble ;
72+
73+ if (iVar13 < - elapsedTimeDouble )
74+ iVar13 = - elapsedTimeDouble ;
5275
53- // change player rotation
54- driver -> angle += iVar13 ;
76+ // change player rotation
77+ driver -> angle += iVar13 ;
5578
56- driver -> axisRotationX -= iVar13 ;
57- driver -> axisRotationX &= 0xfff ;
58-
59- #ifdef USE_60FPS
60- }
61- #endif
79+ driver -> axisRotationX -= iVar13 ;
80+ driver -> axisRotationX &= 0xfff ;
6281 }
6382
6483 // positive cam spin rate
@@ -275,26 +294,34 @@ void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver*
275294 // inverting newMin and newMax will give an inverse range mapping
276295 iVar15 = DECOMP_VehCalc_MapToRange (iVar15 , 0 , iVar11 << 8 , 0 , iVar8 );
277296
278- #ifdef USE_60FPS
297+ iVar12_D = (iVar12_D + iVar15 ) - driver -> turnAngleCurr ;
298+
299+
300+ // Same trick as above ">>3"
301+ // which has more comments there
302+ #ifndef USE_60FPS
303+ iVar15 = iVar12_D >> 3 ;
304+ #else
279305 if (gGT -> timer & 1 )
280306 {
307+ iVar15 = iVar12_D >> 4 ;
308+ }
309+ else
310+ {
311+ iVar15 = (iVar12_D * 16 ) / 15 ;
312+ iVar15 = iVar12_D >> 3 ;
313+ }
281314 #endif
282315
283- iVar12_D = (iVar12_D + iVar15 ) - driver -> turnAngleCurr ;
284- iVar15 = iVar12_D >> 3 ;
285- sVar5 = ( short ) iVar15 ;
286- if (iVar12_D ! = 0 )
316+ sVar5 = (short ) iVar15 ;
317+ if ( iVar12_D != 0 )
318+ {
319+ if (iVar15 = = 0 )
287320 {
288- if (iVar15 == 0 )
289- {
290- sVar5 = 1 ;
291- }
292- driver -> turnAngleCurr += sVar5 ;
321+ sVar5 = 1 ;
293322 }
294-
295- #ifdef USE_60FPS
323+ driver -> turnAngleCurr += sVar5 ;
296324 }
297- #endif
298325
299326 // abs value: numFramesDrifting
300327 iVar12_E = driver -> KartStates .Drifting .numFramesDrifting ;
@@ -402,41 +429,47 @@ void DECOMP_VehPhysProc_PowerSlide_PhysAngular(struct Thread* th, struct Driver*
402429
403430void PhysLerpRot (struct Driver * driver , int iVar13 )
404431{
405- #ifdef USE_60FPS
406- if (sdata -> gGT -> timer & 1 )
432+ int uVar14 ;
433+
434+ // abs value: spinDistRemain
435+ int iVar12_C = driver -> rotCurr .w - iVar13 ;
436+ if (iVar12_C < 0 )
437+ iVar12_C = - iVar12_C ;
438+
439+ // Same trick as above ">>3"
440+ // which has more comments there
441+ #ifndef USE_60FPS
442+ uVar14 = iVar12_C >> 3 ;
443+ #else
444+ if (sdata -> gGT -> timer & 1 )
407445 {
446+ uVar14 = iVar12_C >> 4 ;
447+ }
448+ else
449+ {
450+ uVar14 = (iVar12_C * 16 ) / 15 ;
451+ uVar14 = iVar12_C >> 3 ;
452+ }
408453 #endif
409454
410- // abs value: spinDistRemain
411- int iVar12_C = driver -> rotCurr .w - iVar13 ;
412- if (iVar12_C < 0 )
413- iVar12_C = - iVar12_C ;
414-
415- // 1/8 abs spinDistRemain
416- int uVar14 = iVar12_C >> 3 ;
417-
418- if (uVar14 == 0 )
419- {
420- uVar14 = 1 ;
421- }
422-
423- // max spin this frame
424- int uVar10 = (u_int )driver -> unk46a ;
425- if ((int )uVar14 < (int )(u_int )driver -> unk46a )
426- {
427- uVar10 = uVar14 ;
428- }
429-
430- // Interpolate rotation by speed
431- driver -> rotPrev .w =
432- DECOMP_VehCalc_InterpBySpeed (
433- (int )driver -> rotPrev .w ,
434- 8 ,
435- uVar10 );
455+ if (uVar14 == 0 )
456+ {
457+ uVar14 = 1 ;
458+ }
436459
437- #ifdef USE_60FPS
460+ // max spin this frame
461+ int uVar10 = (u_int )driver -> unk46a ;
462+ if ((int )uVar14 < (int )(u_int )driver -> unk46a )
463+ {
464+ uVar10 = uVar14 ;
438465 }
439- #endif
466+
467+ // Interpolate rotation by speed
468+ driver -> rotPrev .w =
469+ DECOMP_VehCalc_InterpBySpeed (
470+ (int )driver -> rotPrev .w ,
471+ 8 ,
472+ uVar10 );
440473
441474 // Interpolate rotation by speed
442475 driver -> rotCurr .w =
0 commit comments