Mag truck

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Re: Mag truck

Postby Bart » Sun Dec 26, 2021 2:25 pm

Hmm... that didn't seem to work. Rather than exhaustively search all occurrences of mftb I simply added a random value in the range [50000,100000] each time the time base was read. This had no effect, which I *think* pretty well rules out timing.

Given that this routine is executed at the beginning before any 3D graphics are shown and that its results are used quite far along into the attract mode, it does seem like it might be using some sort of value derived from hardware. I tried adding some arbitrary values to the state of the magtruck lever inputs (in case they were being used as a seed value) but that had no effect.

One thing I noticed is that IRQ 0x20 (function unknown and possibly not connected to anything) is the only IRQ that will hang the game unless I explicitly deassert it after some time. But triggering it doesn't do anything.

I guess this leaves little choice but to analyze the code further and see what contributes to the calculation of those rotation values.
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Mag truck

Postby Ian » Sun Dec 26, 2021 2:40 pm

Not sure if this helps. But many games don't use euler angles, they use quaternions instead. A quaternion is kind of like a normal vector with magnitude. They have the format w,x,y,z or sometimes x,y,z,w. They generally avoid gimbal lock and are easy to interpolate, which you can't do with matrices.

Sounds like the game is essentially calculating the camera matrix, the base matrix which all other objects are relative to.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Mag truck

Postby gm_matthew » Mon Dec 27, 2021 12:58 pm

Here is a decompilation of the subroutine where the divisions by zero happen, generated by Ghidra and tidied up a little (I've removed some float/double conversion to make it easier to read):

Code: Select all
void FUN_001466c4(double x, double y, double z)

{
  double dVar1;
  double dVar2;
  double dVar3;
  float local_30[9]; // 3x3 matrix
 
  dVar2 = sqrt(x*x + z*z);
  dVar3 = sqrt(x*x + y*y + z*z);
  dVar1 = x / dVar2;

  local_30[3] = 0.0;
  local_30[4] = dVar2 / dVar3;
  local_30[5] = y / dVar3;
  local_30[0] = z / dVar2;
  local_30[1] = -local_30[5] * dVar1;
  local_30[2] = local_30[4] * dVar1;
  local_30[6] = -dVar1;
  local_30[7] = -local_30[5] * local_30[0];
  local_30[8] = local_30[4] * local_30[0];

  // multiply matrix at top of the matrix stack (pointed to by 0x1258) by local_30
  FUN_00146158(local_30);
}

I'm not sure exactly what this subroutine is meant to do; anyone else have some idea?

Magical Truck Adventure uses a matrix stack of sorts, where matrix transformation functions always work on the matrix on top of the stack. The stack pointer is at 0x1258 (technically 0x1258 + r2, but r2 seems to be always zero). Up to 20 matrices can be put on the stack.
gm_matthew
 
Posts: 224
Joined: Fri Oct 07, 2011 7:29 am
Location: Bristol, UK

Re: Mag truck

Postby Ian » Mon Dec 27, 2021 1:59 pm

A 3x3 matrix is usually just a rotation matrix (maybe scale matrix too)

At first glance given just 3 inputs x,y,z it's probably creating a rotation matrix from a normal vector. Doesn't look like quarterion because would need a w parameter. Could also be euler angles specified in radians instead of degrees.

I'm on my phone miles from my desk but should be able to work out what the maths is doing.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Mag truck

Postby Ian » Mon Dec 27, 2021 5:14 pm

Mathew which is the first div by zero? Surely it should throw a Nan doing the square root first? Does Square root of zero return Nan or zero?

Looking at documentation for c++ square root it returns this

If the argument is less than -0, FE_INVALID is raised and NaN is returned.
If the argument is +∞ or ±0, it is returned, unmodified.

Wonder if powerpc function is the same
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Mag truck

Postby gm_matthew » Mon Dec 27, 2021 7:56 pm

Ian wrote:Mathew which is the first div by zero? Surely it should throw a Nan doing the square root first? Does Square root of zero return Nan or zero?

Looking at documentation for c++ square root it returns this

If the argument is less than -0, FE_INVALID is raised and NaN is returned.
If the argument is +∞ or ±0, it is returned, unmodified.

Wonder if powerpc function is the same

I see no reason why the PowerPC 603 should deviate from this behaviour.

The first NaN is created at 0x14670c (local_30[0] = z / dVar2) which is 0/0. The "dVar1 = x / dVar2" bit actually occurs afterwards (I rearranged for tidiness), though it doesn't matter exactly which one occurs first as the resulting 3x3 matrix is the same; six of the nine values end up as NaNs.
gm_matthew
 
Posts: 224
Joined: Fri Oct 07, 2011 7:29 am
Location: Bristol, UK

Re: Mag truck

Postby Ian » Tue Dec 28, 2021 2:16 am

I checked the sqrt function it behaves the same. I posted online to see what others thought this function did exactly, got this reply.

It's only valid if the vector has at least some X or Z component. If the input vector is just Y, then you'll get a NaN. It also fails if the input is the 0 vector.

It rotates the input so that Z faces in the direction of the input vector, and X is always in the X/Z plane.

If I had to guess, it's a "LookAt" function, and fails when looking straight up.



Where do the x and y values come from? The error must be earlier in the program
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Mag truck

Postby gm_matthew » Tue Dec 28, 2021 4:10 am

A “LookAt” function sounds like it would make sense. The x, y and z values are formed by subtracting one vector from another (0x24f424 and 0x24f430 - I forget which way round off the top of my head); presumably one vector is the camera position and the other is the position of the object to be looked at.
gm_matthew
 
Posts: 224
Joined: Fri Oct 07, 2011 7:29 am
Location: Bristol, UK

Re: Mag truck

Postby gm_matthew » Tue Dec 28, 2021 6:10 am

I decided to try hacking the game so that instead of passing the result of subtracting vector 0x24f424 from 0x24f430 to FUN_001466c4, it just passes the vector 0x24f430. Here is the result:

https://youtu.be/YriOq3zGRuE

The camera no longer looks in the correct direction but apart from that everything seems to be rendering correctly.

From this video it seems that the camera should be fixed on the handcar.

UPDATE: I've figured out that vector 0x24f424 is definitely the camera position.
gm_matthew
 
Posts: 224
Joined: Fri Oct 07, 2011 7:29 am
Location: Bristol, UK

Re: Mag truck

Postby Ian » Tue Dec 28, 2021 11:40 am

Lol, that's super impressive you managed to hack it to draw something:)

Yeah the camera definitely see off compared to the real h/w.

I suppose the question is why is the camera position not updating? There must be some routine that updates it?
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

PreviousNext

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 1 guest