Needle colour mod

From Stunts Wiki

This article refers to a Stunts mod coded by Cas with quite some work from Daniel3D by editing the Restunts source and recompiling it, which allows to configure the instrument needle colour as seen from a car cockpit for each car individually.

History

On 22 August 2021, Ryoma created a thread where he mentioned he had had some success changing the instrument needle colour by creating a mask for one of his cars. Daniel3D noted that this wasn't a complete solution and decided to look into the Restunts code to find a better way to do it. He realised the instrument needle colour was actually defined by reference and not hard-coded, as there is a needle_meter_color pointer in the code.

This called the attention of Cas, who noticed that the pointer actually referenced a constant field, yet, it could be changed for a pointer to a variable. He correctly guessed that there should be a field in memory at a static offset relative to needle_meter_color that would lay within the car RES information and be currently unused, so changing this pointer to make reference to that field would allow for cars to have a configurable needle colour.

Originally, the idea was to just patch the binary by finding the pointer value and replace it, but this turned out to be challenging, so Daniel3D helped with recompilation of the source. Red #5 field was chosen because its default value is 16, which is white in Stunts. This worked flawlessly and it's the first version of the mod.

Then, Cas thought it could be possible to configure different colours for the two instrument needles, but this would require to push new code into the source. Both Cas and Daniel3D worked hard to get this done because this would produce artifacts and made the code unstable. With some padding bytes and several tries, they finally got it working. This is the new version and it has so far proved very stable, although it's impossible to confirm it can never lead to errors.

Technical details

The code Daniel3D initially identified in ReStunts is located in the seg005.asm segment source file and it looks like this:

loc_23456:

   cmp     [bp+var_6], 0
   jnz     short loc_23485
   mov     ax, si
   shl     ax, 1
   mov     [bp+var_20], ax
   push    meter_needle_color
   mov     bx, ax
   mov     al, (simd_player.spdpoints+1)[bx]
   sub     ah, ah
   push    ax
   mov     al, simd_player.spdpoints[bx]
   push    ax
   push    simd_player.spdcenter.y2
   push    simd_player.spdcenter.x2
   call    preRender_line
   add     sp, 0Ah

loc_23485:

   mov     ax, di
   shl     ax, 1
   mov     [bp+var_20], ax
   push    meter_needle_color
   mov     bx, ax
   mov     al, (simd_player.revpoints+1)[bx]
   sub     ah, ah
   push    ax
   mov     al, simd_player.revpoints[bx]
   push    ax
   push    simd_player.revcenter.y2
   push    simd_player.revcenter.x2
   call    preRender_line
   add     sp, 0Ah
   mov     al, [bp+var_2]
   cbw
   or      ax, ax
   jz      short loc_234BE
   cmp     ax, 2           ; st. whl. position flag
   jz      short loc_234EC
   jmp     short loc_234DE
   ; align 2
   db 144

Here, meter_needle_color is a pointer and at that location, there is a single fixed byte with the number 15, which is white in Stunts. Cas searched and found a region of the code where the car information was loaded and among the so-called "mysterious fields", picked one that had the value 16 on all original and old custom cars, because 16 is also white in Stunts. Then he proposed to change the push line to:

push simd_player.field_A6+4