Showing posts with label dot. Show all posts
Showing posts with label dot. Show all posts

Sunday, 14 December 2014

Twenty years of Skidmarks

Lately I've been digging through the old Skidmarks archives, and I came across this wee gem from 1993, no doubt written with lots of help from Simon:

Function.q hite {di.q,dj.q,oset.l}
  UNLK a4
  MOVE.l d2,a0
  MOVE.l d1,d2:SWAP d2:EXT.l d2:ASL.l #7,d2:ADD.l d2,a0
  MOVE.l d0,d2:SWAP d2:EXT.l d2:ASL.l #1,d2:ADD.l d2,a0

  MOVEM (a0)+,d2-d3 ;d0-d1 xy d2-d5 p0-p3
  LEA 124(a0),a0:MOVEM (a0)+,d4-d5
         MOVE d0,d6:MULU d1,d6:SWAP d6:MULU d6,d5  ; x. y.p3
  NOT d0:MOVE d0,d6:MULU d1,d6:SWAP d6:MULU d6,d4  ;-x. y.p2
  NOT d1:MOVE d0,d6:MULU d1,d6:SWAP d6:MULU d6,d2  ;-x.-y.p0
  NOT d0:           MULU d1,d0:SWAP d0:MULU d3,d0   ; x.-y.p1
  ADD.l d2,d0:ADD.l d4,d0:ADD.l d5,d0 ;total
  LSR.l#6,d0:RTS
End Function

For those not quite brave enough to decipher the 68000 assembly, here's what a strictly literal translation might be:

float Height(float x, float y, short *heightField){
  //__asm{...}
  heightField += int(x) * 64;
  heightField += int(y);

  short height2 = *heightfield++, height3 = *heightField++;
  heightField += 62; short height4=*heightfield++, height5 = *heightField++;
  float result5 = frac( x) * frac( y) * height5;
  float result4 = frac(-x) * frac( y) * height4;
  float result2 = frac(-x) * frac(-y) * height2;
  float result0 = frac( x) * frac(-y) * height0;
  float result = (result0 + result2 + result4 + result5);
  return result / 64;
}

The motivation is that I've been working towards a new version for mobile devices, with a working title of "Super Skidmarks 2000" (hashtag #SS2K)

Here's what the modern version of that same function looks like, this time in C++ :

float SKTrack::GetHeight(float axisI,float axisJ)const{
  int fi=(int)floor(axisI);
  int fj=(int)floor(axisJ);

  if(fi<0||fi>=63){
    return 0.0f;
  }
  if(fj<0||fj>=63){
   return 0.0f;
  }
  int index=fi+fj*64;
  float v0=HeightField[index];
  float v1=HeightField[index+1];
  float v2=HeightField[index+64];
  float v3=HeightField[index+65];

  float s=axisI-floor(axisI);
  float t=axisJ-floor(axisJ);

  float v01=v0*(1.0f-s)+v1*s;
  float v23=v2*(1.0f-s)+v3*s;

  float height=v01*(1.0f-t)+v23*t;
  return height;
}


As always, any questions / comments, or suggestion for a better name etc, please leave a comment below!