#include <stdio.h>
#include <stdlib.h>
/* decoding 3d models stored in spherical coordinates.

   x=r.sin(azimuth).cos(zenith)
   y=r.sin(azimuth).sin(zenith)
   z=r.cos(azimuth)

   Test models from https://6502disassembly.com/a2-stellar7/LEV1.html
                and https://6502disassembly.com/a2-stellar7/LEV7.html
*/

typedef long fp14; // There are some architecture dependencies in this code (long vs long long, signed shifts etc)

#define int2fp(x) ((x) << 14)
#define fp2int(x) ((x) >> 14)

const fp14 qsine[65] = {
     0,    402,    803,   1205,   1605,   2005,   2404,   2801, 
  3196,   3589,   3980,   4369,   4756,   5139,   5519,   5896, 
  6269,   6639,   7005,   7366,   7723,   8075,   8423,   8765, 
  9102,   9434,   9759,  10079,  10393,  10701,  11002,  11297, 
 11585,  11866,  12139,  12406,  12665,  12916,  13159,  13395, 
 13622,  13842,  14053,  14255,  14449,  14634,  14810,  14978, 
 15136,  15286,  15426,  15557,  15678,  15790,  15892,  15985, 
 16069,  16142,  16206,  16260,  16305,  16339,  16364,  16379, 
 16384,
};

static inline fp14 hsine(unsigned char x) {
  return x>=64 ? qsine[128-x] : qsine[x];
}

static inline fp14 sine(unsigned char x) {
  return x&0x80 ? -hsine(x&0x7f) : hsine(x);
}

#define fpSin(x) (sine((x) & 0xff))
#define fpCos(x) (sine(((x)+64) & 0xff))

int x[256], y[256], z[256];
void Decode(char *model, int rotation, const unsigned char *p) {
  int r, azimuth, zenith;
  int p1, p2, i = 0;
  fprintf(stdout, "const int8_t %s_%d[] = {\n", model,rotation);
  for (;;) {
    r = *p++; if (r==0x80) break;
    azimuth = *p++;
    zenith = *p++;
    x[i] = fp2int(fp2int(r*fpSin(azimuth+rotation))*fpCos(zenith));
    y[i] = fp2int(fp2int(r*fpSin(azimuth+rotation))*fpSin(zenith));
    z[i] = fp2int(r*fpCos(azimuth+rotation));
    i += 1;
  }
  // got and converted points, now get line segments.
  for (;;) {
    p1 = *p++; if (p1==0x80) break;
    p2 = *p++;
    fprintf(stdout, "  {%d,%d,%d}, {%d,%d,%d},\n", x[p1],y[p1],z[p1],  x[p2],y[p2],z[p2]);
  }
  fprintf(stdout, "  {0,0,0}, {0,0,0}\n");
  fprintf(stdout, "}\n");
}
#define decode(s,r) Decode(#s,r,s)
int main(int argc, char **argv) {
  const unsigned char shp_hovercraft[] = {
   0x46,0x40,0xe2,   0x3c,0x80,0xe2,   0x50,0xc0,0xe2,   0x3c,0x00,0xe2,
   0x32,0x40,0xd3,   0x28,0x80,0xf1,   0x28,0x80,0xd3,   0x3c,0xc0,0xf1,
   0x3c,0xc0,0xd3,   0x28,0x00,0xf1,   0x28,0x00,0xd3,   0x1b,0x50,0x0f,
   0x1b,0x30,0x0f,   0x2d,0x3c,0xfb,   0x31,0x3d,0xf6,   0x2d,0x44,0xfb,
   0x31,0x43,0xf6,   0x64,0x3e,0xfb,   0x64,0x3e,0xf6,   0x64,0x42,0xfb,
   0x64,0x42,0xf6,
   0x80,
   0x00,0x01,   0x01,0x02,   0x02,0x03,   0x03,0x00,
   0x04,0x06,   0x06,0x08,   0x08,0x0a,   0x0a,0x04,
   0x05,0x07,   0x07,0x09,   0x09,0x05,   0x0b,0x0c,
   0x00,0x04,   0x01,0x06,   0x02,0x08,   0x03,0x0a,
   0x01,0x05,   0x02,0x07,   0x03,0x09,   0x05,0x0b,
   0x09,0x0c,   0x00,0x0b,   0x00,0x0c,   0x0d,0x11,
   0x0f,0x13,   0x0e,0x12,   0x10,0x14,   0x11,0x13,
   0x12,0x14,   0x11,0x12,   0x13,0x14,   0x0d,0x0f,
   0x0e,0x10,   0x0d,0x0e,   0x0f,0x10,
   0x80
  };
  decode(shp_hovercraft, 0);
  decode(shp_hovercraft, 128);
  exit(0);
  return(0);
}