Просмотр исходного кода

Added movement to raycaster. Speed improvements to raycaster and script to precalculate direction and plane values for rotation, for each degree.

bart 1 год назад
Родитель
Сommit
f746bbd20d
2 измененных файлов с 359 добавлено и 33 удалено
  1. 291 33
      BCC/userBDOS/RAYCAST.C
  2. 68 0
      Graphics/Raycast/generateDirPlaneValues.py

+ 291 - 33
BCC/userBDOS/RAYCAST.C

@@ -15,6 +15,11 @@
 #define mapWidth 24
 #define mapHeight 24
 
+#define BTN_LEFT 256
+#define BTN_RIGHT 257
+#define BTN_UP 258
+#define BTN_DOWN 259
+
 // Colors
 #define COLOR_RED         224
 #define COLOR_DARK_RED    96
@@ -34,6 +39,144 @@ char (*fb)[screenWidth] = (char (*)[screenWidth]) FB_ADDR;
 
 word quitGame = 0;
 
+word LUTdirX[360] = {
+-65526, -65496, -65446, -65376, -65287, -65177, -65048, -64898, -64729, -64540, -64332, -64104, 
+-63856, -63589, -63303, -62997, -62672, -62328, -61966, -61584, -61183, -60764, -60326, -59870, 
+-59396, -58903, -58393, -57865, -57319, -56756, -56175, -55578, -54963, -54332, -53684, -53020, 
+-52339, -51643, -50931, -50203, -49461, -48703, -47930, -47143, -46341, -45525, -44695, -43852, 
+-42995, -42126, -41243, -40348, -39441, -38521, -37590, -36647, -35693, -34729, -33754, -32768, 
+-31772, -30767, -29753, -28729, -27697, -26656, -25607, -24550, -23486, -22415, -21336, -20252, 
+-19161, -18064, -16962, -15855, -14742, -13626, -12505, -11380, -10252, -9121, -7987, -6850, 
+-5712, -4572, -3430, -2287, -1144, 0, 1144, 2287, 3430, 4572, 5712, 6850, 
+7987, 9121, 10252, 11380, 12505, 13626, 14742, 15855, 16962, 18064, 19161, 20252, 
+21336, 22415, 23486, 24550, 25607, 26656, 27697, 28729, 29753, 30767, 31772, 32768, 
+33754, 34729, 35693, 36647, 37590, 38521, 39441, 40348, 41243, 42126, 42995, 43852, 
+44695, 45525, 46341, 47143, 47930, 48703, 49461, 50203, 50931, 51643, 52339, 53020, 
+53684, 54332, 54963, 55578, 56175, 56756, 57319, 57865, 58393, 58903, 59396, 59870, 
+60326, 60764, 61183, 61584, 61966, 62328, 62672, 62997, 63303, 63589, 63856, 64104, 
+64332, 64540, 64729, 64898, 65048, 65177, 65287, 65376, 65446, 65496, 65526, 65536, 
+65526, 65496, 65446, 65376, 65287, 65177, 65048, 64898, 64729, 64540, 64332, 64104, 
+63856, 63589, 63303, 62997, 62672, 62328, 61966, 61584, 61183, 60764, 60326, 59870, 
+59396, 58903, 58393, 57865, 57319, 56756, 56175, 55578, 54963, 54332, 53684, 53020, 
+52339, 51643, 50931, 50203, 49461, 48703, 47930, 47143, 46341, 45525, 44695, 43852, 
+42995, 42126, 41243, 40348, 39441, 38521, 37590, 36647, 35693, 34729, 33754, 32768, 
+31772, 30767, 29753, 28729, 27697, 26656, 25607, 24550, 23486, 22415, 21336, 20252, 
+19161, 18064, 16962, 15855, 14742, 13626, 12505, 11380, 10252, 9121, 7987, 6850, 
+5712, 4572, 3430, 2287, 1144, 0, -1144, -2287, -3430, -4572, -5712, -6850, 
+-7987, -9121, -10252, -11380, -12505, -13626, -14742, -15855, -16962, -18064, -19161, -20252, 
+-21336, -22415, -23486, -24550, -25607, -26656, -27697, -28729, -29753, -30767, -31772, -32768, 
+-33754, -34729, -35693, -36647, -37590, -38521, -39441, -40348, -41243, -42126, -42995, -43852, 
+-44695, -45525, -46341, -47143, -47930, -48703, -49461, -50203, -50931, -51643, -52339, -53020, 
+-53684, -54332, -54963, -55578, -56175, -56756, -57319, -57865, -58393, -58903, -59396, -59870, 
+-60326, -60764, -61183, -61584, -61966, -62328, -62672, -62997, -63303, -63589, -63856, -64104, 
+-64332, -64540, -64729, -64898, -65048, -65177, -65287, -65376, -65446, -65496, -65526, -65536
+};
+
+
+
+word LUTdirY[360] = {
+1144, 2287, 3430, 4572, 5712, 6850, 7987, 9121, 10252, 11380, 12505, 13626, 
+14742, 15855, 16962, 18064, 19161, 20252, 21336, 22415, 23486, 24550, 25607, 26656, 
+27697, 28729, 29753, 30767, 31772, 32768, 33754, 34729, 35693, 36647, 37590, 38521, 
+39441, 40348, 41243, 42126, 42995, 43852, 44695, 45525, 46341, 47143, 47930, 48703, 
+49461, 50203, 50931, 51643, 52339, 53020, 53684, 54332, 54963, 55578, 56175, 56756, 
+57319, 57865, 58393, 58903, 59396, 59870, 60326, 60764, 61183, 61584, 61966, 62328, 
+62672, 62997, 63303, 63589, 63856, 64104, 64332, 64540, 64729, 64898, 65048, 65177, 
+65287, 65376, 65446, 65496, 65526, 65536, 65526, 65496, 65446, 65376, 65287, 65177, 
+65048, 64898, 64729, 64540, 64332, 64104, 63856, 63589, 63303, 62997, 62672, 62328, 
+61966, 61584, 61183, 60764, 60326, 59870, 59396, 58903, 58393, 57865, 57319, 56756, 
+56175, 55578, 54963, 54332, 53684, 53020, 52339, 51643, 50931, 50203, 49461, 48703, 
+47930, 47143, 46341, 45525, 44695, 43852, 42995, 42126, 41243, 40348, 39441, 38521, 
+37590, 36647, 35693, 34729, 33754, 32768, 31772, 30767, 29753, 28729, 27697, 26656, 
+25607, 24550, 23486, 22415, 21336, 20252, 19161, 18064, 16962, 15855, 14742, 13626, 
+12505, 11380, 10252, 9121, 7987, 6850, 5712, 4572, 3430, 2287, 1144, 0, 
+-1144, -2287, -3430, -4572, -5712, -6850, -7987, -9121, -10252, -11380, -12505, -13626, 
+-14742, -15855, -16962, -18064, -19161, -20252, -21336, -22415, -23486, -24550, -25607, -26656, 
+-27697, -28729, -29753, -30767, -31772, -32768, -33754, -34729, -35693, -36647, -37590, -38521, 
+-39441, -40348, -41243, -42126, -42995, -43852, -44695, -45525, -46341, -47143, -47930, -48703, 
+-49461, -50203, -50931, -51643, -52339, -53020, -53684, -54332, -54963, -55578, -56175, -56756, 
+-57319, -57865, -58393, -58903, -59396, -59870, -60326, -60764, -61183, -61584, -61966, -62328, 
+-62672, -62997, -63303, -63589, -63856, -64104, -64332, -64540, -64729, -64898, -65048, -65177, 
+-65287, -65376, -65446, -65496, -65526, -65536, -65526, -65496, -65446, -65376, -65287, -65177, 
+-65048, -64898, -64729, -64540, -64332, -64104, -63856, -63589, -63303, -62997, -62672, -62328, 
+-61966, -61584, -61183, -60764, -60326, -59870, -59396, -58903, -58393, -57865, -57319, -56756, 
+-56175, -55578, -54963, -54332, -53684, -53020, -52339, -51643, -50931, -50203, -49461, -48703, 
+-47930, -47143, -46341, -45525, -44695, -43852, -42995, -42126, -41243, -40348, -39441, -38521, 
+-37590, -36647, -35693, -34729, -33754, -32768, -31772, -30767, -29753, -28729, -27697, -26656, 
+-25607, -24550, -23486, -22415, -21336, -20252, -19161, -18064, -16962, -15855, -14742, -13626, 
+-12505, -11380, -10252, -9121, -7987, -6850, -5712, -4572, -3430, -2287, -1144, 0
+};
+
+
+
+word LUTplaneX[360] = {
+755, 1510, 2264, 3017, 3770, 4521, 5271, 6020, 6766, 7511, 8253, 8993, 
+9730, 10464, 11195, 11922, 12646, 13366, 14082, 14794, 15501, 16203, 16901, 17593, 
+18280, 18961, 19637, 20306, 20970, 21627, 22277, 22921, 23558, 24187, 24809, 25424, 
+26031, 26630, 27220, 27803, 28377, 28942, 29499, 30047, 30585, 31114, 31634, 32144, 
+32644, 33134, 33614, 34084, 34544, 34993, 35431, 35859, 36276, 36681, 37076, 37459, 
+37831, 38191, 38539, 38876, 39201, 39514, 39815, 40104, 40381, 40645, 40897, 41137, 
+41364, 41578, 41780, 41969, 42145, 42309, 42459, 42597, 42721, 42833, 42931, 43017, 
+43089, 43148, 43194, 43227, 43247, 43254, 43247, 43227, 43194, 43148, 43089, 43017, 
+42931, 42833, 42721, 42597, 42459, 42309, 42145, 41969, 41780, 41578, 41364, 41137, 
+40897, 40645, 40381, 40104, 39815, 39514, 39201, 38876, 38539, 38191, 37831, 37459, 
+37076, 36681, 36276, 35859, 35431, 34993, 34544, 34084, 33614, 33134, 32644, 32144, 
+31634, 31114, 30585, 30047, 29499, 28942, 28377, 27803, 27220, 26630, 26031, 25424, 
+24809, 24187, 23558, 22921, 22277, 21627, 20970, 20306, 19637, 18961, 18280, 17593, 
+16901, 16203, 15501, 14794, 14082, 13366, 12646, 11922, 11195, 10464, 9730, 8993, 
+8253, 7511, 6766, 6020, 5271, 4521, 3770, 3017, 2264, 1510, 755, 0, 
+-755, -1510, -2264, -3017, -3770, -4521, -5271, -6020, -6766, -7511, -8253, -8993, 
+-9730, -10464, -11195, -11922, -12646, -13366, -14082, -14794, -15501, -16203, -16901, -17593, 
+-18280, -18961, -19637, -20306, -20970, -21627, -22277, -22921, -23558, -24187, -24809, -25424, 
+-26031, -26630, -27220, -27803, -28377, -28942, -29499, -30047, -30585, -31114, -31634, -32144, 
+-32644, -33134, -33614, -34084, -34544, -34993, -35431, -35859, -36276, -36681, -37076, -37459, 
+-37831, -38191, -38539, -38876, -39201, -39514, -39815, -40104, -40381, -40645, -40897, -41137, 
+-41364, -41578, -41780, -41969, -42145, -42309, -42459, -42597, -42721, -42833, -42931, -43017, 
+-43089, -43148, -43194, -43227, -43247, -43254, -43247, -43227, -43194, -43148, -43089, -43017, 
+-42931, -42833, -42721, -42597, -42459, -42309, -42145, -41969, -41780, -41578, -41364, -41137, 
+-40897, -40645, -40381, -40104, -39815, -39514, -39201, -38876, -38539, -38191, -37831, -37459, 
+-37076, -36681, -36276, -35859, -35431, -34993, -34544, -34084, -33614, -33134, -32644, -32144, 
+-31634, -31114, -30585, -30047, -29499, -28942, -28377, -27803, -27220, -26630, -26031, -25424, 
+-24809, -24187, -23558, -22921, -22277, -21627, -20970, -20306, -19637, -18961, -18280, -17593, 
+-16901, -16203, -15501, -14794, -14082, -13366, -12646, -11922, -11195, -10464, -9730, -8993, 
+-8253, -7511, -6766, -6020, -5271, -4521, -3770, -3017, -2264, -1510, -755, 0
+};
+
+
+
+word LUTplaneY[360] = {
+43247, 43227, 43194, 43148, 43089, 43017, 42931, 42833, 42721, 42597, 42459, 42309, 
+42145, 41969, 41780, 41578, 41364, 41137, 40897, 40645, 40381, 40104, 39815, 39514, 
+39201, 38876, 38539, 38191, 37831, 37459, 37076, 36681, 36276, 35859, 35431, 34993, 
+34544, 34084, 33614, 33134, 32644, 32144, 31634, 31114, 30585, 30047, 29499, 28942, 
+28377, 27803, 27220, 26630, 26031, 25424, 24809, 24187, 23558, 22921, 22277, 21627, 
+20970, 20306, 19637, 18961, 18280, 17593, 16901, 16203, 15501, 14794, 14082, 13366, 
+12646, 11922, 11195, 10464, 9730, 8993, 8253, 7511, 6766, 6020, 5271, 4521, 
+3770, 3017, 2264, 1510, 755, 0, -755, -1510, -2264, -3017, -3770, -4521, 
+-5271, -6020, -6766, -7511, -8253, -8993, -9730, -10464, -11195, -11922, -12646, -13366, 
+-14082, -14794, -15501, -16203, -16901, -17593, -18280, -18961, -19637, -20306, -20970, -21627, 
+-22277, -22921, -23558, -24187, -24809, -25424, -26031, -26630, -27220, -27803, -28377, -28942, 
+-29499, -30047, -30585, -31114, -31634, -32144, -32644, -33134, -33614, -34084, -34544, -34993, 
+-35431, -35859, -36276, -36681, -37076, -37459, -37831, -38191, -38539, -38876, -39201, -39514, 
+-39815, -40104, -40381, -40645, -40897, -41137, -41364, -41578, -41780, -41969, -42145, -42309, 
+-42459, -42597, -42721, -42833, -42931, -43017, -43089, -43148, -43194, -43227, -43247, -43254, 
+-43247, -43227, -43194, -43148, -43089, -43017, -42931, -42833, -42721, -42597, -42459, -42309, 
+-42145, -41969, -41780, -41578, -41364, -41137, -40897, -40645, -40381, -40104, -39815, -39514, 
+-39201, -38876, -38539, -38191, -37831, -37459, -37076, -36681, -36276, -35859, -35431, -34993, 
+-34544, -34084, -33614, -33134, -32644, -32144, -31634, -31114, -30585, -30047, -29499, -28942, 
+-28377, -27803, -27220, -26630, -26031, -25424, -24809, -24187, -23558, -22921, -22277, -21627, 
+-20970, -20306, -19637, -18961, -18280, -17593, -16901, -16203, -15501, -14794, -14082, -13366, 
+-12646, -11922, -11195, -10464, -9730, -8993, -8253, -7511, -6766, -6020, -5271, -4521, 
+-3770, -3017, -2264, -1510, -755, 0, 755, 1510, 2264, 3017, 3770, 4521, 
+5271, 6020, 6766, 7511, 8253, 8993, 9730, 10464, 11195, 11922, 12646, 13366, 
+14082, 14794, 15501, 16203, 16901, 17593, 18280, 18961, 19637, 20306, 20970, 21627, 
+22277, 22921, 23558, 24187, 24809, 25424, 26031, 26630, 27220, 27803, 28377, 28942, 
+29499, 30047, 30585, 31114, 31634, 32144, 32644, 33134, 33614, 34084, 34544, 34993, 
+35431, 35859, 36276, 36681, 37076, 37459, 37831, 38191, 38539, 38876, 39201, 39514, 
+39815, 40104, 40381, 40645, 40897, 41137, 41364, 41578, 41780, 41969, 42145, 42309, 
+42459, 42597, 42721, 42833, 42931, 43017, 43089, 43148, 43194, 43227, 43247, 43254
+};
+
 word worldMap[mapWidth][mapHeight]=
 {
   {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
@@ -62,21 +205,66 @@ word worldMap[mapWidth][mapHeight]=
   {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
 };
 
+// Render vertical line in pixel plane
+// INPUT:
+//   r4 = x (which vertical line)
+//   r5 = y when to start drawing line
+//   r6 = y when to stop drawing line
+//   r7 = color of line
 void RAYFX_drawVertLine(word x, word start, word end, char color)
 {
-  word y = 0;
-  while (y < screenHeight)
-  {
-    if (y >= start && y <= end)
-    {
-      fb[y][x] = color;
-    }
-    else
-    {
-      fb[y][x] = 0;
-    }
-    y++;
-  }
+  // reg 4 5 6 7 and 2 (retval) are safe
+  asm(
+  "; backup registers\n"
+  "push r9\n"
+  );
+
+  asm(
+
+  "load32 0xD00000 r9   ; r9 = framebuffer addr\n"
+  "add r9 r4 r4         ; r4 = first pixel in line\n"
+
+  "multu r5 320 r9      ; r9 = start with line offset\n"
+  "add r9 r4 r5         ; r5 = fb addr of start\n"
+  
+  "multu r6 320 r9      ; r9 = end with line offset\n"
+  "add r9 r4 r6         ; r6 = fb addr of start\n"
+
+  "load 239 r2          ; r2 = y endloop\n"
+  "multu r2 320 r9      ; r9 = start line offset\n"
+  "add r9 r4 r2         ; r2 = fb addr of final pixel\n"
+
+  "; draw until start\n"
+  "RAYFX_drawVlineLoopCeiling:\n"
+  "  write 0 r4 r0     ; write black pixel\n"
+  "  add r4 320 r4     ; go to next line pixel\n"
+
+  "  bge r4 r5 2       ; keep looping until reached start\n"
+  "  jump RAYFX_drawVlineLoopCeiling\n"
+
+  "; draw until end\n"
+  "RAYFX_drawVlineLoopWall:\n"
+  "  write 0 r4 r7     ; write color pixel\n"
+  "  add r4 320 r4     ; go to next line pixel\n"
+
+  "  bge r4 r6 2       ; keep looping until reached end\n"
+  "  jump RAYFX_drawVlineLoopWall\n"
+
+
+  "; draw until final pixel\n"
+  "RAYFX_drawVlineLoopFloor:\n"
+  "  write 0 r4 r0     ; write black pixel\n"
+  "  add r4 320 r4     ; go to next line pixel\n"
+
+  "  bge r4 r2 2       ; keep looping until reached end of screen\n"
+  "  jump RAYFX_drawVlineLoopFloor\n"
+  );
+
+  asm(
+  "; restore registers\n"
+  "pop r9\n"
+  );
+
 }
 
 int main() 
@@ -87,24 +275,23 @@ int main()
   GFX_clearBGtileTable();
   GFX_clearBGpaletteTable();
 
-  // tmp precalculated values for rotation
-  fixed_point_t sinval = FP_StringToFP("-0.0998");
-  fixed_point_t cosval = FP_StringToFP("0.995");
-
   //x and y start position
   fixed_point_t posX = FP_intToFP(12);
   fixed_point_t posY = FP_intToFP(12);
 
   //initial direction vector
-  fixed_point_t dirX = FP_intToFP(-1);
-  fixed_point_t dirY = 0;
+  fixed_point_t dirX = LUTdirX[0];
+  fixed_point_t dirY = LUTdirY[0];
 
   //the 2d raycaster version of camera plane
-  fixed_point_t planeX = 0;
-  fixed_point_t planeY = FP_StringToFP("0.66");
+  fixed_point_t planeX = LUTplaneX[0];
+  fixed_point_t planeY = LUTplaneY[0];
+
+  // rotation angle (loops at 360)
+  word rotationAngle = 0;
+  word rotationSpeed = 3; // degrees per frame
 
-  fixed_point_t time = 0; //time of current frame
-  fixed_point_t oldTime = 0; //time of previous frame
+  fixed_point_t moveSpeed = FP_StringToFP("0.15");
 
   while(!quitGame)
   {
@@ -113,6 +300,7 @@ int main()
     {
       //calculate ray position and direction
       fixed_point_t cameraX = FP_Div(FP_intToFP(x<<1), FP_intToFP(screenWidth)) - FP_intToFP(1); //x-coordinate in camera space
+
       fixed_point_t rayDirX = dirX + FP_Mult(planeX, cameraX);
       fixed_point_t rayDirY = dirY + FP_Mult(planeY, cameraX);
 
@@ -219,18 +407,88 @@ int main()
       }
 
       //draw the pixels of the stripe as a vertical line
-      RAYFX_drawVertLine(x, drawStart, drawEnd, color);
+      // Safity checks beforehand
+      // Currently skips first line of frame as it does not render properly
+      if (x != 0 && drawStart >= 0 && drawEnd >= drawStart && drawEnd < screenHeight)
+      {
+        RAYFX_drawVertLine(x, drawStart, drawEnd, color);
+      }
     }
 
-    
-    // TMP go right
-    //both camera direction and camera plane must be rotated
-    fixed_point_t oldDirX = dirX;
-    dirX = FP_Mult(dirX, cosval) - FP_Mult(dirY , sinval);
-    dirY = FP_Mult(oldDirX, sinval) + FP_Mult(dirY, cosval);
-    fixed_point_t oldPlaneX = planeX;
-    planeX = FP_Mult(planeX, cosval) - FP_Mult(planeY, sinval);
-    planeY = FP_Mult(oldPlaneX, sinval) + FP_Mult(planeY, cosval);
+
+    // check which button is held
+    if (BDOS_USBkeyHeld(BTN_LEFT))
+    {
+      //both camera direction and camera plane must be rotated
+      rotationAngle -= rotationSpeed;
+      if (rotationAngle < 0)
+      {
+        rotationAngle += 360;
+      }
+      dirX = LUTdirX[rotationAngle];
+      dirY = LUTdirY[rotationAngle];
+      planeX = LUTplaneX[rotationAngle];
+      planeY = LUTplaneY[rotationAngle];
+    }
+    else if (BDOS_USBkeyHeld(BTN_RIGHT))
+    {
+      //both camera direction and camera plane must be rotated
+      rotationAngle += rotationSpeed;
+      if (rotationAngle >= 360)
+      {
+        rotationAngle -= 360;
+      }
+      dirX = LUTdirX[rotationAngle];
+      dirY = LUTdirY[rotationAngle];
+      planeX = LUTplaneX[rotationAngle];
+      planeY = LUTplaneY[rotationAngle];
+    }
+
+    if (BDOS_USBkeyHeld(BTN_UP))
+    {
+      word worldMapX = FP_FPtoInt(posX + FP_Mult(dirX, moveSpeed));
+      word worldMapY = FP_FPtoInt(posY);
+
+      if(worldMap[worldMapX][worldMapY] == 0)
+      {
+        posX += FP_Mult(dirX, moveSpeed);
+      }
+
+      worldMapX = FP_FPtoInt(posX);
+      worldMapY = FP_FPtoInt(posY + FP_Mult(dirY, moveSpeed));
+      if(worldMap[worldMapX][worldMapY] == 0)
+      {
+        posY += FP_Mult(dirY, moveSpeed);
+      }
+    }
+    else if (BDOS_USBkeyHeld(BTN_DOWN))
+    {
+      word worldMapX = FP_FPtoInt(posX - FP_Mult(dirX, moveSpeed));
+      word worldMapY = FP_FPtoInt(posY);
+
+      if(worldMap[worldMapX][worldMapY] == 0)
+      {
+        posX -= FP_Mult(dirX, moveSpeed);
+      }
+
+      worldMapX = FP_FPtoInt(posX);
+      worldMapY = FP_FPtoInt(posY - FP_Mult(dirY, moveSpeed));
+      if(worldMap[worldMapX][worldMapY] == 0)
+      {
+        posY -= FP_Mult(dirY, moveSpeed);
+      }
+    }
+
+    if (HID_FifoAvailable())
+    {
+      word c = HID_FifoRead();
+
+      if (c == 27) // escape
+      {
+        GFX_clearPXframebuffer();
+        return 'q';
+      }
+    }
     
   }
 

+ 68 - 0
Graphics/Raycast/generateDirPlaneValues.py

@@ -0,0 +1,68 @@
+# Script to precalculate dir and plane values, as this keeps them in sync
+# However, this means no dynamic adjustments of the FOV,
+#  as this is determined by the ratio between dir and plane vectors
+#  currently resulting in an FOV of 2*atan(0.66/1.0)=66°
+
+from math import cos, sin, pi, pow
+
+functionsToCreateTableOf = ["dirX", "dirY", "planeX", "planeY"]
+
+
+dirX = -1.0
+dirY = 0.0
+planeX = 0.0
+planeY = 0.66
+
+def doubleToFP16(x):
+    return round(x * pow(2,16))
+
+# Original code quickly converted to python
+#rotate to the right
+def moveRight(rotSpeed, function):
+    global dirX
+    global dirY
+    global planeX
+    global planeY
+
+    #both camera direction and camera plane must be rotated
+    oldDirX = dirX
+    dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed)
+    dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed)
+
+    oldPlaneX = planeX
+    planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed)
+    planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed)
+
+    #print("dx:{:.5f} dy:{:.5f} px:{:.5f} py:{:.5f}".format(dirX, dirY, planeX, planeY) )
+
+    if function == "dirX":
+        print(str(doubleToFP16(dirX)) + ", ", end='')
+
+    elif function == "dirY":
+        print(str(doubleToFP16(dirY)) + ", ", end='')
+
+    elif function == "planeX":
+        print(str(doubleToFP16(planeX)) + ", ", end='')
+
+    elif function == "planeY":
+        print(str(doubleToFP16(planeY)) + ", ", end='')
+
+# pi/180 means 360 even steps -> one per degree (so use 360 as looplength)
+rotSpeed = pi/180
+loopLength = 360
+
+# Create lookup table for each function
+for function in functionsToCreateTableOf:
+    # reset to make sure
+    dirX = -1.0
+    dirY = 0.0
+    planeX = 0.0
+    planeY = 0.66
+
+    print("word LUT"+function + "[" + str(loopLength) + "] = {")
+    for i in range(loopLength):
+        moveRight(rotSpeed, function)
+        if (i+1) % 12 == 0:
+            print()
+    print("};")
+    print("\n\n")