Author Topic: Flight simulator  (Read 7396 times)

0 Members and 1 Guest are viewing this topic.

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Flight simulator
« on: November 03, 2021, 09:14:35 pm »
Hello !
I'm thinking of a game. I’ve tried a shooter-like game before, now I want something that shows the speed. I was thinking of a fighter simulator. (I really want a car game, but to this day I can't approach the physics of the car)
Because the plane is fast and a trajectory flies over quickly, I generated the seemingly random ground from a function.
I searched the net for a solution and found a very interesting solution to the real-time endless trajectory: Perlin noise. I used this.
Check it out, it’s interesting, and it can be used for a lot of things.
https://www.arendpeter.com/Perlin_Noise.html
We're just racing for now. By turning the whole thing left and right, we turn and “turn” with the A-D keys. If you become an enemy, it may be interesting to shoot him.
The source code is concise, but whoever cares will disassemble it.

Code: QB64: [Select]
  1. 'mikrolepes
  2.  
  3. Const pip180 = 3.141592 / 180
  4. Const perlin_pers = 7 'amplitudo
  5. Const perlin_level = 5 'level of resolution wave
  6. Const perlin_multiplier = 0.006
  7. Const perlin_smooth_noise_interpolation_type = 0 '0-none '1-standard
  8. Const perlin_flat_soil_limit = .8
  9. monx = _DesktopWidth * .7: mony = monx / 16 * 9 'screen size
  10.  
  11. map_shadow = 18
  12. position_speed = .7
  13. map_resolution = 70
  14.  
  15. map_dimxy = 1200
  16. map_dimz = 250
  17.  
  18. map_zoom_xy = 6
  19. map_zoom_distance = 15
  20. mouse_sens_xy = .01
  21. mouse_sens_z = .01
  22.  
  23. cam(4) = pip180 * 270
  24.  
  25. me(0) = 2000: me(1) = 2000
  26.  
  27. 'create pseudo random buffer
  28. Dim Shared noise_rand_c: noise_rand_c = 10000: Dim Shared noise_rand(noise_rand_c - 1): For t = 0 To noise_rand_c - 1: noise_rand(t) = Rnd(1): Next t
  29.  
  30. 'create texture
  31. Dim color_temp As _Integer64: Dim Shared mapz_min, mapz_max
  32. text_size = 8: text_size_marg = 8: text_deep = 40: text_height_scale = 15: Dim texture(text_height_scale - 1, text_deep - 1)
  33. For t = 0 To text_deep - 1: For t2 = 0 To text_height_scale - 1
  34.     dark = 1 - (1 / text_deep * t)
  35.     color_temp = _RGB32((255 * dark), (100 * dark), ((255 / text_height_scale * t2)) * dark)
  36.     temp = _NewImage(text_size, text_size, 32): _Dest temp: Cls: marg = text_size * text_size_marg / 100
  37. Line (marg, marg)-(text_size - marg, text_size - marg), color_temp, BF: texture(t2, t) = _CopyImage(temp, 33): _FreeImage temp: Next t2, t
  38.  
  39. 'find min/max Z
  40. mapz_min = 9999999: mapz_max = -mapz_min: For t = 0 To 1999: c = Perlin2D(1000 * Rnd(1), 1000 * Rnd(1))
  41.     If mapz_min > c Then mapz_min = c
  42.     If mapz_max < c Then mapz_max = c
  43.  
  44.  
  45. 'fill map-buffer
  46. Dim map(map_resolution - 1, map_resolution - 1, 5): perl_setx = Int(me(0)): perl_sety = Int(me(1))
  47. For map_x = 0 To map_resolution - 1: For map_y = 0 To map_resolution - 1: map_z = Perlin2D(perl_setx + map_x, perl_sety + map_y)
  48. map((map_x + perl_setx) Mod map_resolution, (map_y + perl_sety) Mod map_resolution, 0) = 1 / (mapz_max - mapz_min) * (map_z - mapz_min): Next map_y, map_x
  49.  
  50.  
  51. mon = _NewImage(monx, mony, 32): Screen mon: _FullScreen: _MouseHide
  52.  
  53. 'MAP array
  54. '0-perlin Z-data
  55. '1-maptriangle calculate X
  56. '2-maptriangle calculate Y
  57. '3-maptriangle calculate Z
  58. '4-distance from me (color)
  59.  
  60.  
  61.  
  62.  
  63.     mousex = 0: mousey = 0: While _MouseInput: mousex = mousex + _MouseMovementX: mousey = mousey + _MouseMovementY: Wend
  64.     'cam(3) = cam(3) + mousex * mouse_sens_xy
  65.     cam(4) = cam(4) + mousey * mouse_sens_z
  66.     '    cam(3) = mouse_sens * .1
  67.     rotx = rotx + mousex / 100
  68.     max_incli = 60: If Abs(rotx) > (max_incli * pip180) Then rotx = max_incli * pip180 * Sgn(rotx)
  69.     cam(3) = cam(3) + rotx / 40
  70.  
  71.     'control position
  72.     kw = _KeyDown(119)
  73.     kw = -1
  74.     ks = _KeyDown(115): ka = _KeyDown(97): kd = _KeyDown(100): new_direction = (Abs(ka Or kd Or kw) Or -Abs(ks)) * position_speed
  75.  
  76.     deg_XY = -90 * Abs(ka) + 90 * Abs(kd)
  77.  
  78.     szog_xy = cam(3) + deg_XY * pip180
  79.  
  80.     '   szog_z = cam(4)
  81.  
  82.     me(0) = me(0) - Sin(szog_xy) * Cos(szog_z) * new_direction
  83.     me(1) = me(1) - Cos(szog_xy) * Cos(szog_z) * new_direction
  84.     '    me(2) = me(2) + SIN(szog_z) * new_direction '* ABS(ka = 0 AND kd = 0)
  85.  
  86.     '    cam(2) = me(2)
  87.     '    LOCATE 1, 1: PRINT cam(2)
  88.  
  89.  
  90.  
  91.     'replace the missing row in the buffer line Y
  92.     Do While Int(Int(me(0))) <> perl_setx: dir = -Sgn(Int(me(0)) - perl_setx): perl_setx = perl_setx - dir
  93.         For map_y = 0 To map_resolution - 1: temp = perl_setx + Abs(dir = -1) * (map_resolution - 1): map_z = Perlin2D(temp, perl_sety + map_y)
  94.     map(temp Mod map_resolution, (map_y + perl_sety) Mod map_resolution, 0) = 1 / (mapz_max - mapz_min) * (map_z - mapz_min): Next map_y: Loop
  95.  
  96.     'replace the missing row in the buffer line X
  97.     Do While Int(Int(me(1))) <> perl_sety: dir = -Sgn(Int(me(1)) - perl_sety): perl_sety = perl_sety - dir
  98.         For map_x = 0 To map_resolution - 1: temp = perl_sety + Abs(dir = -1) * (map_resolution - 1): map_z = Perlin2D(perl_setx + map_x, temp)
  99.     map((map_x + perl_setx) Mod map_resolution, temp Mod map_resolution, 0) = 1 / (mapz_max - mapz_min) * (map_z - mapz_min): Next map_x: Loop
  100.  
  101.  
  102.  
  103.     cosrotz = Cos(cam(3)): sinrotz = Sin(cam(3)): cosrotx = Cos(cam(4)): sinrotx = Sin(cam(4))
  104.  
  105.     'calculating position and textures
  106.     '    e1 = perl_setx - INT(perl_setx)
  107.  
  108.     '   e2 = perl_sety - INT(perl_sety)
  109.     For map_x = 0 To map_resolution - 1: px = -map_dimxy / 2 + map_dimxy / map_resolution * (map_x - e1) - cam(0)
  110.         For map_y = 0 To map_resolution - 1: py = -map_dimxy / 2 + map_dimxy / map_resolution * (map_y - e2) - cam(1)
  111.             map_z = map((map_x + perl_setx) Mod map_resolution, (map_y + perl_sety) Mod map_resolution, 0)
  112.             If map_z > perlin_flat_soil_limit Then map_z = perlin_flat_soil_limit
  113.             pz2 = map_dimz * map_z - cam(2)
  114.             px3 = px * cosrotz - py * sinrotz: py2 = px * sinrotz + py * cosrotz: py3 = py2 * cosrotx - pz2 * sinrotx: pz3 = py2 * sinrotx + pz2 * cosrotx
  115.             px4 = (px3 * Cos(rotx)) - (py3 * Sin(rotx)): py4 = (px3 * Sin(rotx)) + (py3 * Cos(rotx))
  116.             map(map_x, map_y, 1) = -px4 * map_zoom_xy: map(map_x, map_y, 2) = -py4 * map_zoom_xy: map(map_x, map_y, 3) = -pz3 * map_zoom_distance
  117.             map(map_x, map_y, 4) = Int(Sqr(px3 * px3 + py3 * py3 + pz3 * pz3) / map_shadow)
  118.             If map(map_x, map_y, 4) > text_deep - 1 Then map(map_x, map_y, 4) = text_deep - 1
  119.             map(map_x, map_y, 5) = Int(text_height_scale * map_z)
  120.             If map(map_x, map_y, 5) > text_height_scale - 1 Then map(map_x, map_y, 5) = text_height_scale - 1
  121.             If map(map_x, map_y, 5) < 0 Then map(map_x, map_y, 5) = 0
  122.     Next map_y, map_x
  123.  
  124.     'do maptriangle from squares !
  125.     For map_x = 0 To map_resolution - 2: For map_y = 0 To map_resolution - 2
  126.         m0x = map(map_x, map_y, 1): m0y = map(map_x, map_y, 2): m0z = map(map_x, map_y, 3)
  127.         m1x = map(map_x + 1, map_y, 1): m1y = map(map_x + 1, map_y, 2): m1z = map(map_x + 1, map_y, 3)
  128.         m2x = map(map_x, map_y + 1, 1): m2y = map(map_x, map_y + 1, 2): m2z = map(map_x, map_y + 1, 3)
  129.         m3x = map(map_x + 1, map_y + 1, 1): m3y = map(map_x + 1, map_y + 1, 2): m3z = map(map_x + 1, map_y + 1, 3)
  130.         atexture = texture(map(map_x, map_y, 5), map(map_x, map_y, 4))
  131.         _MapTriangle (0, 0)-(text_size - 1, 0)-(0, text_size - 1), atexture To(m0x, m0y, m0z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  132.         _MapTriangle (0, 0)-(text_size - 1, 0)-(0, text_size - 1), atexture To(m3x, m3y, m3z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  133.     Next map_y, map_x
  134.  
  135.     _Display: Cls
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142. Function noise (x, y) 'reading pseudo random buffer
  143.     x2 = Int(x): y2 = Int(y): a = Int(Abs(x2) + Abs(y2)) Mod noise_rand_c: b = Abs(x2) Mod noise_rand_c: c = noise_rand(a) + noise_rand(b): noise = c - Int(c)
  144.  
  145. Function SmoothNoise (x, y)
  146.     Select Case perlin_smooth_noise_interpolation_type
  147.         Case 0: SmoothNoise = noise(x, y)
  148.         Case 1: corners = (noise(x - 1, y - 1) + noise(x + 1, y - 1) + noise(x - 1, y + 1) + noise(x + 1, y + 1)) / 16
  149.             sides = (noise(x - 1, y) + noise(x + 1, y) + noise(x, y - 1) + noise(x, y + 1)) / 8: center = noise(x, y) / 4: SmoothNoise = corners + sides + center
  150.     End Select
  151.  
  152. Function Perlin2D (x, y): total = 0: For t = 0 To perlin_level - 1: frequency = 2 ^ t * perlin_multiplier: amplitude = perlin_pers ^ t
  153.     total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude: Next t: Perlin2D = total
  154.  
  155. Function InterpolatedNoise (x, y): integer_X = Int(x): fractional_X = x - integer_X: integer_y = Int(y): fractional_Y = y - integer_y
  156.     v1 = SmoothNoise(integer_X, integer_y): v2 = SmoothNoise(integer_X + 1, integer_y)
  157.     v3 = SmoothNoise(integer_X, integer_y + 1): v4 = SmoothNoise(integer_X + 1, integer_y + 1)
  158.     i1 = Interpolate(v1, v2, fractional_X): i2 = Interpolate(v3, v4, fractional_X): InterpolatedNoise = Interpolate(i1, i2, fractional_Y)
  159.  
  160. Function Interpolate (a, b, x): Interpolate = a * (1 - x) + b * x: End Function
  161.  
  162.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Flight simulator
« Reply #1 on: November 04, 2021, 01:15:38 pm »
More genius work from MasterGy! Nice :)

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Flight simulator
« Reply #2 on: November 04, 2021, 03:26:50 pm »
Very nicely done! So quick and smooth. Reminds me of the old DOS game 'Magic Carpet'... Looking forward to the next iteration...
Logic is the beginning of wisdom.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Flight simulator
« Reply #3 on: November 05, 2021, 09:14:22 am »
More genius work from MasterGy! Nice :)

@bplus is not wrong.  Very impressive (up to the standard of @Ashish with _GL) terrain.  Don't fancy trying to land a plane on that terrain, though!

If you just let this code run, it eventually crashes (aeronautical pun!).
terrain.jpg

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Flight simulator
« Reply #4 on: November 05, 2021, 10:18:07 am »
How long for you before it crashes? @Qwerkey

Heck of a line (101):
Code: QB64: [Select]
  1. map((map_x + perl_setx) Mod map_resolution, temp Mod map_resolution, 0) = 1 / (mapz_max - mapz_min) * (map_z - mapz_min): Next map_x: Loop


Map is 3 dim's
Code: QB64: [Select]
  1. Dim map(map_resolution - 1, map_resolution - 1, 5)
  2.  

I see only 1 comma inside a () inside line 101???


Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Flight simulator
« Reply #5 on: November 05, 2021, 01:14:09 pm »
Hello !
Thanks for trying it! I didn’t know the “Magic Carpet” game, but I watched it and really like the scenery! I imagined a similar graphic, I wish it would look like mine.
Yes, you are right that real physics, real fighter control, proper runway would be hard to put together from that. I don't strive for 100% reality, but rather I just want to show the feeling of speed, flight, speed, that would give the gaming experience.
I always develop in QB64 1.3 because it creates an exe quickly. When do you experience a crash? I haven't had such a problem yet.
Bplus, the MAP array records a lot. Calculating an elevation point with “perlin” takes a long time, so the MAP array is a buffer. As we move on the track, it always counts only the next X or Y row, then adds it to the MAP array and shifts the entire array by 1.
The position of the points, the distance of the point from us, the height value, and more can be used to determine objects, such as trees, columns, flowers, based on different conditions. To be or not to be in a particular place.
Thank you Qwerky for making a mistake. In vain do I think, I do not understand why the address of the array may have fallen out of range. I put INT in it, I hope it filters out the trouble.
I refined it a bit more. I want it to look like “Magic Carpet”.

Code: QB64: [Select]
  1. 'mikrolepes
  2.  
  3. CONST pip180 = 3.141592 / 180
  4. CONST perlin_pers = 7 'amplitudo
  5. CONST perlin_level = 5 'level of resolution wave
  6. CONST perlin_multiplier = 0.006
  7. CONST perlin_smooth_noise_interpolation_type = 0 '0-none '1-standard
  8. CONST perlin_flat_soil_limit = .8
  9. DIM SHARED rotating(2), cosrotz, sinrotz, cosrotx, sinrotx, map_zoom_xy, map_zoom_distance, rotx
  10.  
  11. monx = _DESKTOPWIDTH * .7: mony = monx / 16 * 9 'screen size
  12.  
  13. map_shadow = 15
  14. position_speed = .6
  15. map_resolution = 60
  16.  
  17. map_dimxy = 1200
  18. map_dimz = 250
  19.  
  20. map_zoom_xy = 6
  21. map_zoom_distance = 15
  22. mouse_sens_xy = .01
  23. mouse_sens_z = .01
  24.  
  25. cam(4) = pip180 * 270
  26.  
  27. me(0) = 2000: me(1) = 2000
  28. DIM clmn(1999, 5): ration_column = 0.001
  29.  
  30.  
  31. 'create pseudo random buffer
  32. DIM SHARED noise_rand_c: noise_rand_c = 10000: DIM SHARED noise_rand(noise_rand_c - 1): FOR t = 0 TO noise_rand_c - 1: noise_rand(t) = RND(1): NEXT t
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39. 'create texture
  40. DIM color_temp AS _INTEGER64: DIM SHARED mapz_min, mapz_max
  41. text_size = 8: text_size_marg = 8: text_deep = 40: text_height_scale = 15: DIM texture(text_height_scale - 1, text_deep - 1)
  42. FOR t = 0 TO text_deep - 1: FOR t2 = 0 TO text_height_scale - 1: dark = 1 - (1 / (text_deep - 1) * t)
  43.         color_temp = _RGB32((255 * dark), (100 * dark), ((255 / text_height_scale * t2)) * dark)
  44.         temp = _NEWIMAGE(text_size, text_size, 32): _DEST temp: CLS: marg = text_size * text_size_marg / 100
  45. LINE (marg, marg)-(text_size - marg, text_size - marg), color_temp, BF: texture(t2, t) = _COPYIMAGE(temp, 33): _FREEIMAGE temp: NEXT t2, t
  46.  
  47.  
  48.  
  49. 'find min/max Z
  50. mapz_min = 9999999: mapz_max = -mapz_min: FOR t = 0 TO 1999: c = Perlin2D(1000 * RND(1), 1000 * RND(1))
  51.     IF mapz_min > c THEN mapz_min = c
  52.     IF mapz_max < c THEN mapz_max = c
  53.  
  54.  
  55. 'fill map-buffer
  56. DIM map(map_resolution - 1, map_resolution - 1, 9): perl_setx = INT(me(0)): perl_sety = INT(me(1))
  57. FOR map_x = 0 TO map_resolution - 1: FOR map_y = 0 TO map_resolution - 1: map_z = Perlin2D(perl_setx + map_x, perl_sety + map_y)
  58.         map((map_x + perl_setx) MOD map_resolution, (map_y + perl_sety) MOD map_resolution, 0) = 1 / (mapz_max - mapz_min) * (map_z - mapz_min)
  59. map((map_x + perl_setx) MOD map_resolution, (map_y + perl_sety) MOD map_resolution, 6) = noise(map_x, map_y) < ration_column: NEXT map_y, map_x
  60.  
  61. mon = _NEWIMAGE(monx, mony, 32): SCREEN mon: _FULLSCREEN: _MOUSEHIDE
  62.  
  63.  
  64. 'MAP array
  65. '0-perlin Z-data
  66. '1-maptriangle calculate X
  67. '2-maptriangle calculate Y
  68. '3-maptriangle calculate Z
  69. '4-distance from me (color)
  70. '5-texture height scale
  71. '6-is there a column ?
  72.  
  73.  
  74.     mousex = 0: mousey = 0: WHILE _MOUSEINPUT: mousex = mousex + _MOUSEMOVEMENTX: mousey = mousey + _MOUSEMOVEMENTY: WEND
  75.     'cam(3) = cam(3) + mousex * mouse_sens_xy
  76.     cam(4) = cam(4) + mousey * mouse_sens_z
  77.     '    cam(3) = mouse_sens * .1
  78.     rotx = rotx + mousex / 150
  79.     max_incli = 60: IF ABS(rotx) > (max_incli * pip180) THEN rotx = max_incli * pip180 * SGN(rotx)
  80.     cam(3) = cam(3) + rotx / 30
  81.  
  82.     'control position
  83.     kw = _KEYDOWN(119)
  84.     '    kw = -1
  85.     ks = _KEYDOWN(115): ka = _KEYDOWN(97): kd = _KEYDOWN(100): new_direction = (ABS(ka OR kd OR kw) OR -ABS(ks)) * position_speed
  86.  
  87.     deg_XY = -90 * ABS(ka) + 90 * ABS(kd)
  88.  
  89.     szog_xy = cam(3) + deg_XY * pip180
  90.  
  91.     '   szog_z = cam(4)
  92.  
  93.     me(0) = me(0) - SIN(szog_xy) * COS(szog_z) * new_direction
  94.     me(1) = me(1) - COS(szog_xy) * COS(szog_z) * new_direction
  95.     '    me(2) = me(2) + SIN(szog_z) * new_direction '* ABS(ka = 0 AND kd = 0)
  96.  
  97.     '    cam(2) = me(2)
  98.     '    LOCATE 1, 1: PRINT cam(2)
  99.  
  100.  
  101.  
  102.     'replace the missing row in the buffer line Y
  103.     DO WHILE INT(INT(me(0))) <> perl_setx: dir = -SGN(INT(me(0)) - perl_setx): perl_setx = perl_setx - dir
  104.         FOR map_y = 0 TO map_resolution - 1: temp = perl_setx + ABS(dir = -1) * (map_resolution - 1): map_z = Perlin2D(temp, perl_sety + map_y)
  105.             map(temp MOD map_resolution, (map_y + perl_sety) MOD map_resolution, 0) = 1 / (mapz_max - mapz_min) * (map_z - mapz_min)
  106.     map(INT(temp MOD map_resolution), INT((map_y + perl_sety) MOD map_resolution), 6) = noise(temp, perl_sety + map_y) < ration_column: NEXT map_y: LOOP
  107.  
  108.     'replace the missing row in the buffer line X
  109.     DO WHILE INT(INT(me(1))) <> perl_sety: dir = -SGN(INT(me(1)) - perl_sety): perl_sety = perl_sety - dir
  110.         FOR map_x = 0 TO map_resolution - 1: temp = perl_sety + ABS(dir = -1) * (map_resolution - 1): map_z = Perlin2D(perl_setx + map_x, temp)
  111.             map(INT((map_x + perl_setx) MOD map_resolution), INT(temp MOD map_resolution), 0) = 1 / (mapz_max - mapz_min) * (map_z - mapz_min)
  112.     map((map_x + perl_setx) MOD map_resolution, temp MOD map_resolution, 6) = noise(perl_setx + map_x, temp) < ration_column: NEXT map_x: LOOP
  113.  
  114.     cosrotz = COS(cam(3)): sinrotz = SIN(cam(3)): cosrotx = COS(cam(4)): sinrotx = SIN(cam(4)) 'to rotating angles
  115.  
  116.     'calculating position and textures
  117.     clmn(0, 0) = 0 'reset column counter
  118.     FOR map_x = 0 TO map_resolution - 1: px = -map_dimxy / 2 + map_dimxy / map_resolution * (map_x - (me(0) - INT(me(0)))) - cam(0)
  119.         FOR map_y = 0 TO map_resolution - 1: py = -map_dimxy / 2 + map_dimxy / map_resolution * (map_y - (me(1) - INT(me(1)))) - cam(1)
  120.             read_mapx = INT((map_x + perl_setx) MOD map_resolution): read_mapy = INT((map_y + perl_sety) MOD map_resolution)
  121.             map_z = map(read_mapx, read_mapy, 0): IF map_z > perlin_flat_soil_limit THEN map_z = perlin_flat_soil_limit
  122.             pz2 = map_dimz * map_z - cam(2): rotate px, py, pz2
  123.             map(map_x, map_y, 1) = rotating(0): map(map_x, map_y, 2) = rotating(1): map(map_x, map_y, 3) = rotating(2)
  124.             map(map_x, map_y, 4) = INT(SQR(px * px + py * py) / map_shadow)
  125.             IF map(map_x, map_y, 4) > text_deep - 1 THEN map(map_x, map_y, 4) = text_deep - 1
  126.             map(map_x, map_y, 5) = INT(text_height_scale * map_z)
  127.             IF map(map_x, map_y, 5) > text_height_scale - 1 THEN map(map_x, map_y, 5) = text_height_scale - 1
  128.             IF map(map_x, map_y, 5) < 0 THEN map(map_x, map_y, 5) = 0
  129.             IF map(read_mapx, read_mapy, 6) THEN clmn(clmn(0, 0) + 1, 2) = map(map_x, map_y, 4): clmn(clmn(0, 0) + 1, 0) = px: clmn(clmn(0, 0) + 1, 1) = py: clmn(0, 0) = clmn(0, 0) + 1
  130.  
  131.     NEXT map_y, map_x
  132.  
  133.     'do maptriangle from squares !
  134.     FOR map_x = 0 TO map_resolution - 2: FOR map_y = 0 TO map_resolution - 2
  135.             m0x = map(map_x, map_y, 1): m0y = map(map_x, map_y, 2): m0z = map(map_x, map_y, 3)
  136.             m1x = map(map_x + 1, map_y, 1): m1y = map(map_x + 1, map_y, 2): m1z = map(map_x + 1, map_y, 3)
  137.             m2x = map(map_x, map_y + 1, 1): m2y = map(map_x, map_y + 1, 2): m2z = map(map_x, map_y + 1, 3)
  138.             m3x = map(map_x + 1, map_y + 1, 1): m3y = map(map_x + 1, map_y + 1, 2): m3z = map(map_x + 1, map_y + 1, 3)
  139.             atexture = texture(map(map_x, map_y, 5), map(map_x, map_y, 4))
  140.             _MAPTRIANGLE (0, 0)-(text_size - 1, 0)-(0, text_size - 1), atexture TO(m0x, m0y, m0z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  141.             _MAPTRIANGLE (0, 0)-(text_size - 1, 0)-(0, text_size - 1), atexture TO(m3x, m3y, m3z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  142.     NEXT map_y, map_x
  143.  
  144.     'draw columns
  145.     ac_ang = 5: ac_rad = 20: column_height = 800: column_rot = column_rot + 1
  146.     FOR ac = 0 TO clmn(0, 0) - 1: FOR t = 0 TO ac_ang - 1: temp = (360 / ac_ang * t + column_rot) * pip180
  147.             px = clmn(ac + 1, 0) + SIN(temp) * ac_rad: py = clmn(ac + 1, 1) + COS(temp) * ac_rad
  148.             pz2 = 400: rotate px, py, pz2: ac(t, 0, 0) = rotating(0): ac(t, 1, 0) = rotating(1): ac(t, 2, 0) = rotating(2)
  149.         pz2 = -300: rotate px, py, pz2: ac(t, 0, 1) = rotating(0): ac(t, 1, 1) = rotating(1): ac(t, 2, 1) = rotating(2): NEXT t
  150.  
  151.         FOR t = 0 TO ac_ang - 1: t2 = (t + 1) MOD ac_ang
  152.             m0x = ac(t, 0, 0): m0y = ac(t, 1, 0): m0z = ac(t, 2, 0): m1x = ac(t2, 0, 0): m1y = ac(t2, 1, 0): m1z = ac(t2, 2, 0)
  153.             m2x = ac(t, 0, 1): m2y = ac(t, 1, 1): m2z = ac(t, 2, 1): m3x = ac(t2, 0, 1): m3y = ac(t2, 1, 1): m3z = ac(t2, 2, 1)
  154.             atexture = texture(0, clmn(ac + 1, 2))
  155.             _MAPTRIANGLE (0, 0)-(text_size - 1, 0)-(0, text_size - 1), atexture TO(m0x, m0y, m0z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  156.             _MAPTRIANGLE (0, 0)-(text_size - 1, 0)-(0, text_size - 1), atexture TO(m3x, m3y, m3z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  157.     NEXT t, ac
  158.  
  159.  
  160.     _DISPLAY: CLS , _RGB32(15, 0, 0)
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168. FUNCTION noise (x, y) 'reading pseudo random buffer
  169.     x2 = INT(x): y2 = INT(y): a = INT(ABS(x2) + ABS(y2)) MOD noise_rand_c: b = ABS(x2) MOD noise_rand_c: c = noise_rand(a) + noise_rand(b): noise = c - INT(c)
  170.  
  171. FUNCTION SmoothNoise (x, y)
  172.     SELECT CASE perlin_smooth_noise_interpolation_type
  173.         CASE 0: SmoothNoise = noise(x, y)
  174.         CASE 1: corners = (noise(x - 1, y - 1) + noise(x + 1, y - 1) + noise(x - 1, y + 1) + noise(x + 1, y + 1)) / 16
  175.             sides = (noise(x - 1, y) + noise(x + 1, y) + noise(x, y - 1) + noise(x, y + 1)) / 8: center = noise(x, y) / 4: SmoothNoise = corners + sides + center
  176.     END SELECT
  177.  
  178. FUNCTION Perlin2D (x, y): total = 0: FOR t = 0 TO perlin_level - 1: frequency = 2 ^ t * perlin_multiplier: amplitude = perlin_pers ^ t
  179.     total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude: NEXT t: Perlin2D = total
  180.  
  181. FUNCTION InterpolatedNoise (x, y): integer_X = INT(x): fractional_X = x - integer_X: integer_y = INT(y): fractional_Y = y - integer_y
  182.     v1 = SmoothNoise(integer_X, integer_y): v2 = SmoothNoise(integer_X + 1, integer_y)
  183.     v3 = SmoothNoise(integer_X, integer_y + 1): v4 = SmoothNoise(integer_X + 1, integer_y + 1)
  184.     i1 = Interpolate(v1, v2, fractional_X): i2 = Interpolate(v3, v4, fractional_X): InterpolatedNoise = Interpolate(i1, i2, fractional_Y)
  185.  
  186. FUNCTION Interpolate (a, b, x): Interpolate = a * (1 - x) + b * x: END FUNCTION
  187.  
  188. SUB rotate (px, py, pz2)
  189.     px3 = px * cosrotz - py * sinrotz: py2 = px * sinrotz + py * cosrotz: py3 = py2 * cosrotx - pz2 * sinrotx: pz3 = py2 * sinrotx + pz2 * cosrotx
  190.     px4 = (px3 * COS(rotx)) - (py3 * SIN(rotx)): py4 = (px3 * SIN(rotx)) + (py3 * COS(rotx))
  191.     rotating(0) = -px4 * map_zoom_xy: rotating(1) = -py4 * map_zoom_xy: rotating(2) = -pz3 * map_zoom_distance
  192.  
  193.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Flight simulator
« Reply #6 on: November 05, 2021, 03:13:11 pm »
OK I ran this for 1 hr 20 mins while lunched, read paper did puzzles and walked dog and no problems when I came back to it (2nd version).

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Flight simulator
« Reply #7 on: November 05, 2021, 05:01:33 pm »
First. Nice improvements. Manual control. Sweet. The rotating "tree trunks" were a surprise... Cool.

This may be a silly question (bplus... don't even think about it... lol) but is it just me that has difficulty exiting the program? I can alt+tab to select QB64 IDE and terminate it, but the demo is still running... I should have read the listing more carefully and inserted an "escape clause"... Moo ha ha...

Still a very cool demo...
Logic is the beginning of wisdom.

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Flight simulator
« Reply #8 on: November 05, 2021, 06:21:26 pm »
What a great demo.  Pretty amazing work!  Small code but does so much.  Well done.

- Dav

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: Flight simulator
« Reply #9 on: November 06, 2021, 09:58:14 pm »
nice work, looks great!  I am interested in this and have been modifying your program, also have some game ideas

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Flight simulator
« Reply #10 on: November 07, 2021, 04:01:03 pm »
Thanks !
Thanks Dav for trying it and the others too!
I’m very curious about your ideas, Vince, and I’m curious about what you modified on it. Where can I see it?
I changed a lot of it. I worked a lot of hours to make it enjoyable to manage. The hills just throw it and slow it down, and it bounces off the columns. When steering, you can feel that it is not just the direction that matters, but the thrust behind us. I wonder what you say about management, I had a lot of work in it. It feels a bit like drifting. You go in one direction at high speed and suddenly I put the force in another direction, but the inertia and thrust play enjoyably. In flight, W is the gas, S is the brake, and all directions can be achieved with the sensual movement of the mouse. If the speed is 0, it will land on the ground by pressing S continuously.
Press F to toggle between flight and walk mode.
Currently, the goal is to get to the “target”.
There’s a lot of computation and I’ve managed to simplify a few things, so far, my otherwise slow machine is comfortable with 40FPS.
I hope that next time a heavenly war can be fought. I thought a lot about how to entrust the control of an enemy machine to the program.

download (2Mb)
https://drive.google.com/file/d/1DWwX1ayPSQLx8rjgWZXhJvx_uCLN9auk/view?usp=sharing



Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Flight simulator
« Reply #11 on: November 08, 2021, 07:41:59 am »
@MasterGy
Great Job!! Looks similar to a "textured" version of this - https://www.qb64.org/forum/index.php?topic=1139.msg103744#msg103744 which has heavily used  Perlin noise.
If you are interested, you can read this article - https://www.redblobgames.com/maps/terrain-from-noise/
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Flight simulator
« Reply #12 on: November 08, 2021, 11:32:38 am »
Ashish, I'm glad you brought it to my attention! I used to watch Openworld and I really liked the graphics. Then I saw that there was opengl in it and I was scared and I didn’t even look further. :)
Now I understand that you also made the map with perlin noise, and even the textures, only with a different approach! I really like you to assign textures to height values. This is how I do the placement of the columns. All I miss is that if you’re already making the map with Perlin noise anyway, why haven’t you made it to infinite expanse. Originally, I was looking for this solution because I wanted an infinite map that would be generated in real time.
What you wrote as a link demonstrates this Perlin noise very well! I like the way the website shows how the map changes when we change a value.
And your opengl solution is a special congratulations, I still don't understand the whole thing :(

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Flight simulator
« Reply #13 on: November 08, 2021, 11:39:26 am »
This is looking great, @MasterGy!  Kind of reminds me of one of my favorite DOS games, Terminal Velocity.  I'll be following this game development!

- Dav

Offline MasterGy

  • Seasoned Forum Regular
  • Posts: 327
  • people lie, math never lies
    • View Profile
Re: Flight simulator
« Reply #14 on: November 08, 2021, 02:38:50 pm »
I promised that I would show the sequel when there was a heavenly battle. This, in turn, required a solution that would take the plane to its destination as efficiently as possible. I have to show it because it’s very spectacular! Everything is the same as before. Press F to toggle between walking, flying, and autopilot. The autopilot goes to the target in a superhuman way, elegantly bypassing the columns at maximum speed.

Code: QB64: [Select]
  1. CONST pip180 = 3.141592 / 180
  2. CONST perlin_pers = 7 'amplitudo
  3. CONST perlin_level = 5 'level of resolution wave
  4. 'CONST perlin_multiplier = 0.006
  5. CONST perlin_multiplier = 0.008
  6. CONST perlin_smooth_noise_interpolation_type = 0 '0-none '1-standard
  7. CONST perlin_flat_soil_limit_low = .8 'high value is low area (negate)
  8. CONST perlin_flat_soil_limit_high = .1
  9. CONST flight_array_size = 20: DIM flight_save(flight_array_size - 1)
  10. DIM SHARED rotating(2), cosrotz, sinrotz, cosrotx, sinrotx, map_zoom_xy, map_zoom_distance, see_point, flight(19, flight_array_size), me(19), rotx_bevel
  11. DIM SHARED mouse_sens_xy, mouse_sens_z, position_speed, clmn_rad
  12. DIM SHARED map_x, map_y, perl_setx, perl_sety, map_resolution, map_z, map_dimz, map_dimxy, flight_high_max
  13. monx = 1366: mony = monx / 16 * 9 'screen size
  14.  
  15. win_marg = monx / 25
  16.  
  17. flight_high_max = -70
  18.  
  19. text_deep = 30 'make deep shadow pictures
  20.  
  21.  
  22. map_center = 100000 'start of perlin-map
  23. text_field$ = "need\field2.bmp"
  24. text_field$ = "need\field1.bmp" 'field map texture
  25. text_multi = 40 'zoom to texture
  26.  
  27. position_speed = .9
  28. map_resolution = 60 'see map resolution
  29. DIM SHARED map_resper2: map_resper2 = INT(map_resolution / 2)
  30.  
  31.  
  32. DIM SHARED max_incli: max_incli = 65 'flight max rotation
  33.  
  34. map_dimxy = 1200 * .8
  35. map_dimz = 250 * .8
  36.  
  37. map_zoom_xy = 6 * .2
  38. map_zoom_distance = 15 * .2
  39.  
  40.  
  41. mouse_sens_xy = 1.6
  42. mouse_sens_z = 1
  43.  
  44. me(6) = pip180 * 270
  45.  
  46. me(0) = map_center: me(1) = map_center
  47.  
  48. control_type$(0) = "walking": control_type$(1) = "flying": control_type$(2) = "flying/autopilot"
  49. DIM color_temp(9) AS _INTEGER64
  50. targ_text = _LOADIMAGE("need\target.jpg", 33)
  51.  
  52.  
  53.  
  54.  
  55.  
  56. DIM clmn(1999, 5): clmn_rad = 30: ration_column = 0.0003: ration_column = 0.002
  57.  
  58.  
  59. 'install radar
  60. rad_ts = 600: rad_size = monx / 5.5: r1 = rad_ts / 2 * .96: r2 = rad_ts / 2 * .80
  61. temp = _NEWIMAGE(rad_ts, rad_ts, 32): _DEST temp: CLS , 0: color_temp(0) = _RGB32(200, 200, 200)
  62. CIRCLE (rad_ts / 2, rad_ts / 2), r1, color_temp(0): CIRCLE (rad_ts / 2, rad_ts / 2), r2, color_temp(0)
  63. PAINT (rad_ts / 2 + (r1 + r2) / 2, rad_ts / 2), color_temp(0), color_temp(0): PAINT (rad_ts / 2, rad_ts / 2), _RGBA(100, 100, 255, 150), color_temp(0)
  64. rad_text = _COPYIMAGE(temp, 33): _FREEIMAGE temp
  65.  
  66. 'radar object
  67. rado_ts = 150: temp = _NEWIMAGE(rado_ts, rado_ts, 32): _DEST temp: CLS , 0: color_temp(0) = _RGB32(180, 0, 0)
  68. CIRCLE (rado_ts / 2, rado_ts / 2), rado_ts / 2 * .98, color_temp(0)
  69. PAINT (rado_ts / 2, rado_ts / 2), color_temp(0), color_temp(0): rado_text = _COPYIMAGE(temp, 33): _FREEIMAGE temp
  70.  
  71. 'make sky
  72. da = 8: db = 8: sky_points = da * db: DIM sky_points(sky_points - 1, 9), sq(sky_points - 1, 7): sky_image = _LOADIMAGE("need\sky.jpg", 33)
  73. FOR da2 = 0 TO da - 1: dega = 360 / (da - 1) * da2 * pip180: FOR db2 = 0 TO db - 1: degb = 180 / (db - 1) * db2 * pip180: ss = 1400
  74. ap = da2 * db + db2: sky_points(ap, 0) = SIN(degb) * COS(dega) * ss: sky_points(ap, 1) = SIN(degb) * SIN(dega) * ss: sky_points(ap, 2) = COS(degb) * ss: NEXT db2, da2
  75. FOR da2 = 0 TO da - 2: FOR db2 = 0 TO db - 2: sqa = da2 * db + db2: sq(sqa, 0) = sqa: sq(sqa, 1) = sq(sqa, 0) + 1: sq(sqa, 2) = sq(sqa, 0) + db: sq(sqa, 3) = sq(sqa, 2) + 1
  76.         sq(sqa, 4) = _WIDTH(sky_image) - (_WIDTH(sky_image) / (da - 1) * da2) - 1: sq(sqa, 5) = _WIDTH(sky_image) - (_WIDTH(sky_image) / (da - 1) * (da2 + 1)) - 1
  77. sq(sqa, 6) = INT(_HEIGHT(sky_image) / (db - 1) * db2): sq(sqa, 7) = INT(_HEIGHT(sky_image) / (db - 1) * (db2 + 1)): NEXT db2, da2
  78.  
  79. 'create pseudo random buffer
  80. DIM SHARED noise_rand_c: noise_rand_c = 10000: DIM SHARED noise_rand(noise_rand_c - 1): FOR t = 0 TO noise_rand_c - 1: noise_rand(t) = RND(1): NEXT t
  81.  
  82. 'create texture
  83. DIM temp_color(9) AS _INTEGER64: DIM SHARED mapz_min, mapz_max: DIM texture(text_deep - 1, 5): temp = _LOADIMAGE(text_field$, 32)
  84. FOR t = 0 TO text_deep - 1: dark = (1 - (1 / (text_deep - 1) * t)): transp = dark * 2000: IF transp > 255 THEN transp = 255
  85.     temp2 = _NEWIMAGE(_WIDTH(temp), _HEIGHT(temp), 32): _SOURCE temp: _DEST temp2: CLS 0, _RGBA32(0, 0, 0, transp)
  86.     FOR tx = 0 TO _WIDTH(temp) - 1: FOR ty = 0 TO _HEIGHT(temp) - 1: temp_color(0) = POINT(tx, ty)
  87.             c1 = _RED32(temp_color(0)) * dark: c2 = _GREEN32(temp_color(0)) * dark: c3 = _BLUE32(temp_color(0)) * dark
  88.     PSET (tx, ty), _RGBA32(c1, c2, c3, transp): NEXT ty, tx: texture(t, 0) = _COPYIMAGE(temp2, 33): _FREEIMAGE temp2
  89.  
  90. 'find min/max Z
  91. DIM SHARED mapz_multiplier: mapz_min = 9999999: mapz_max = -mapz_min: FOR t = 0 TO 2999: c = Perlin2D_original(5000 * RND(1), 5000 * RND(1))
  92.     mapz_min = c * ABS(mapz_min > c) + mapz_min * (ABS(mapz_min > c) XOR 1): mapz_max = c * ABS(mapz_max < c) + mapz_max * (ABS(mapz_max < c) XOR 1)
  93. NEXT t: mapz_multiplier = 1 / (mapz_max - mapz_min)
  94.  
  95.  
  96. 'fill map-buffer
  97. DIM SHARED map(map_resolution - 1, map_resolution - 1, 19): perl_setx = INT(me(0)): perl_sety = INT(me(1))
  98. FOR map_x = 0 TO map_resolution - 1: FOR map_y = 0 TO map_resolution - 1
  99.         map((map_x + perl_setx) MOD map_resolution, (map_y + perl_sety) MOD map_resolution, 0) = perlin2d(perl_setx + map_x, perl_sety + map_y)
  100. map((map_x + perl_setx) MOD map_resolution, (map_y + perl_sety) MOD map_resolution, 6) = noise(map_x, map_y) < ration_column: NEXT map_y, map_x
  101.  
  102. 'calculating shadows
  103. FOR map_x = 0 TO map_resolution - 1: FOR map_y = 0 TO map_resolution - 1
  104.         dis = INT((text_deep - 1) / map_resper2 * SQR((map_x - map_resper2) ^ 2 + (map_y - map_resper2) ^ 2)): IF dis < 0 OR dis > text_deep - 1 THEN _CONTINUE
  105. map(map_x, map_y, 9) = 1: map(map_x, map_y, 8) = dis: NEXT map_y, map_x
  106.  
  107.  
  108.  
  109.  
  110. 'MAP array
  111. '0-perlin Z-data
  112. '1-maptriangle calculate X
  113. '2-maptriangle calculate Y
  114. '3-maptriangle calculate Z
  115. '4-distance from me (color)
  116. '5-texture height scale
  117. '6-is there a column ?
  118. '7-is the point visible?
  119. '8-shadow-table
  120. '9-not used area signal
  121.  
  122. 'ME array
  123. '0-me X location
  124. '1-me Y location
  125. '2-me Z location
  126. '3-vector_x
  127. '4-vector_y
  128. '5-me XY angle CAM3
  129. '6-me XY CAM4
  130. '7-me kanyarodas merteke
  131.  
  132. 'FLIGHT array
  133. '0-active
  134. '1-rotx - kanyarodas merteke
  135. '2-rotx_bevel
  136. '3-location X
  137. '4-location Y
  138. '5-location Z
  139. '6-vector X
  140. '7-vector Y
  141. '8-W gas
  142. '9-S brake
  143. '10-mouseX
  144. '11-mouseZ
  145. '12 cam4  /me6
  146. '13 cam3 /me5
  147. '15 actual speed
  148. '16 column (XY) crash /last step
  149. '17 land (Z) crash /last step
  150.  
  151.  
  152. auto_precalc = 28
  153. auto_mouse_scale = 140
  154. auto_try_resolution = 22
  155. DIM flight_auto(auto_try_resolution - 1, flight_array_size - 1)
  156. DIM auto_efficiency(auto_try_resolution - 1, 5) '0- 1 if crash          '1- target-flight distance
  157.  
  158.  
  159.  
  160.  
  161. GOSUB new_target
  162. control_type = 0
  163.  
  164.  
  165.  
  166.  
  167. _PRINTSTRING (0, 0), "moving:mouse+WASD jump:space walking/fly: F"
  168.     kf = _KEYDOWN(102): k_space = _KEYDOWN(32)
  169.     kw = _KEYDOWN(119): ks = _KEYDOWN(115): mousex = 0: mousey = 0: WHILE _MOUSEINPUT: mousex = mousex + _MOUSEMOVEMENTX: mousey = mousey + _MOUSEMOVEMENTY: WEND
  170.  
  171.     IF ut_kf = 0 AND kf THEN control_type = (control_type + 1) MOD 3
  172.     ut_kf = kf
  173.  
  174.     walk_speed = .18
  175.  
  176.  
  177.     _PRINTSTRING (500, 0), "control type : " + control_type$(control_type) + "           "
  178.  
  179.     SELECT CASE control_type '(0-walking 1-flying)
  180.         CASE 0
  181.             me(3) = 0: me(4) = 0: me(7) = 0: flight(0, 1) = 0
  182.             me(5) = me(5) + mousex * mouse_sens_xy / 200: me(6) = me(6) + mousey * mouse_sens_xy / 200
  183.             kw = _KEYDOWN(119): ks = _KEYDOWN(115): ka = _KEYDOWN(97): kd = _KEYDOWN(100)
  184.             go = ABS(ka OR kd OR kw OR ks): direction = (-90 * ABS(ka) + 90 * ABS(kd) + 180 * ABS(ks)) * go * pip180
  185.             go_x = -(SIN(direction + me(5)) * walk_speed) * go: go_y = -(COS(direction + me(5)) * walk_speed) * go
  186.             IF crash_to_column(me(0) + go_x, me(1) + go_y) THEN go_x = 0: go_y = 0
  187.  
  188.             me(0) = me(0) + go_x: me(1) = me(1) + go_y
  189.  
  190.             IF jump_cf = 0 THEN
  191.                 IF (map_deep(me(0), me(1)) - .18) * map_dimz > me(2) THEN
  192.                     walk_c_down = walk_c_down + .2: me(2) = me(2) + walk_c_down: free_jump = 0
  193.                 ELSE walk_c_down = 0: me(2) = (map_deep(me(0), me(1)) - .18) * map_dimz: free_jump = 1
  194.                 END IF
  195.             END IF
  196.  
  197.             IF k_space AND free_jump THEN jump_cf = 15
  198.             rotx_bevel = rotx_bevel * .95: me(2) = me(2) - jump_cf / 4: jump_cf = jump_cf - 1: IF jump_cf < 0 THEN jump_cf = 0
  199.  
  200.  
  201.         CASE 1
  202.             'contact between me and flight0
  203.             flight(0, 2) = rotx_bevel: flight(0, 8) = ABS(kw): flight(0, 9) = ABS(ks): flight(0, 10) = mousex * mouse_sens_xy: flight(0, 11) = mousey * mouse_sens_z
  204.             flight(0, 3) = me(0): flight(0, 4) = me(1): flight(0, 5) = me(2): flight(0, 6) = me(3): flight(0, 7) = me(4): flight(0, 12) = me(6): flight(0, 13) = me(5)
  205.             flight_control 0, 0
  206.             me(0) = flight(0, 3): me(1) = flight(0, 4): me(2) = flight(0, 5): me(3) = flight(0, 6): me(4) = flight(0, 7): me(5) = flight(0, 13): me(6) = flight(0, 12)
  207.             rotx_bevel = flight(0, 2)
  208.         CASE 2 'autopilot
  209.  
  210.             flight(0, 2) = rotx_bevel: flight(0, 8) = ABS(kw): flight(0, 9) = ABS(ks): flight(0, 10) = mousex * mouse_sens_xy: flight(0, 11) = mousey * mouse_sens_z
  211.             flight(0, 3) = me(0): flight(0, 4) = me(1): flight(0, 5) = me(2): flight(0, 6) = me(3): flight(0, 7) = me(4): flight(0, 12) = me(6): flight(0, 13) = me(5)
  212.  
  213.             FOR t = 0 TO flight_array_size - 1: flight_save(t) = flight(0, t): NEXT t
  214.  
  215.             'calculation of options
  216.             FOR a_try = 0 TO auto_try_resolution - 1: auto_efficiency(a_try, 0) = 0
  217.                 FOR t = 0 TO flight_array_size - 1: flight(0, t) = flight_save(t): NEXT t
  218.                 flight(0, 8) = 1: flight(0, 10) = -auto_mouse_scale + (auto_mouse_scale * 2) / (auto_try_resolution - 1) * a_try
  219.                 FOR a_pre = 1 TO auto_precalc: flight_control 0, 1: IF flight(0, 16) THEN EXIT FOR
  220.                 NEXT a_pre: IF flight(0, 16) THEN auto_efficiency(a_try, 0) = 1: _CONTINUE
  221.             auto_efficiency(a_try, 1) = ABS((targ(0) - flight(0, 3)) ^ 2 + (targ(1) - flight(0, 4)) ^ 2): NEXT a_try
  222.  
  223.             'choosing the most effective option
  224.             adis = 999999: auto_opt = -1: FOR t = 0 TO auto_try_resolution - 1
  225.                 IF auto_efficiency(t, 0) = 0 AND auto_efficiency(t, 1) < adis THEN adis = auto_efficiency(t, 1): auto_opt = t
  226.             NEXT t: IF auto_opt = -1 THEN auto_opt = INT(auto_try_resolution * RND(1)): auto_rand = auto_rand + 1
  227.  
  228.             FOR t = 0 TO flight_array_size - 1: flight(0, t) = flight_save(t): NEXT t
  229.             flight(0, 8) = 1: flight(0, 10) = -auto_mouse_scale + (auto_mouse_scale * 2) / (auto_try_resolution - 1) * auto_opt: flight_control 0, 0
  230.             me(0) = flight(0, 3): me(1) = flight(0, 4): me(2) = flight(0, 5): me(3) = flight(0, 6): me(4) = flight(0, 7): me(5) = flight(0, 13): me(6) = flight(0, 12)
  231.             rotx_bevel = flight(0, 2)
  232.  
  233.     END SELECT
  234.  
  235.  
  236.  
  237.     'replace the missing row in the buffer line Y
  238.     DO WHILE INT(INT(me(0))) <> perl_setx: dir = -SGN(INT(me(0)) - perl_setx): perl_setx = perl_setx - dir
  239.         temp = INT(perl_setx + ABS(dir = -1) * (map_resolution - 1)): temp_m = INT(temp MOD map_resolution)
  240.         FOR map_y = 0 TO map_resolution - 1: map(temp_m, INT(map_y + perl_sety) MOD map_resolution, 0) = perlin2d(temp, perl_sety + map_y)
  241.     map(temp_m, INT((map_y + perl_sety) MOD map_resolution), 6) = noise(temp, perl_sety + map_y) < ration_column: NEXT map_y: LOOP
  242.  
  243.     'replace the missing row in the buffer line X
  244.     DO WHILE INT(INT(me(1))) <> perl_sety: dir = -SGN(INT(me(1)) - perl_sety): perl_sety = perl_sety - dir
  245.         temp = perl_sety + ABS(dir = -1) * (map_resolution - 1): temp_m = INT(temp MOD map_resolution)
  246.         FOR map_x = 0 TO map_resolution - 1: map(INT((map_x + perl_setx) MOD map_resolution), temp_m, 0) = perlin2d(perl_setx + map_x, temp)
  247.     map(INT(map_x + perl_setx) MOD map_resolution, temp_m, 6) = noise(perl_setx + map_x, temp) < ration_column: NEXT map_x: LOOP
  248.  
  249.     cosrotz = COS(me(5)): sinrotz = SIN(me(5)): cosrotx = COS(me(6)): sinrotx = SIN(me(6)) 'to rotating angles
  250.  
  251.  
  252.     'draw sky
  253.     FOR actual_point = 0 TO sky_points - 1: rotate sky_points(actual_point, 0), sky_points(actual_point, 1), sky_points(actual_point, 2), 0
  254.     sky_points(actual_point, 4) = rotating(0): sky_points(actual_point, 5) = rotating(1): sky_points(actual_point, 6) = rotating(2): NEXT actual_point
  255.     FOR asq = 0 TO sky_points - 1
  256.         wx0 = sky_points(sq(asq, 0), 4): wy0 = sky_points(sq(asq, 0), 5): wz0 = sky_points(sq(asq, 0), 6)
  257.         wx1 = sky_points(sq(asq, 1), 4): wy1 = sky_points(sq(asq, 1), 5): wz1 = sky_points(sq(asq, 1), 6)
  258.         wx2 = sky_points(sq(asq, 2), 4): wy2 = sky_points(sq(asq, 2), 5): wz2 = sky_points(sq(asq, 2), 6)
  259.         wx3 = sky_points(sq(asq, 3), 4): wy3 = sky_points(sq(asq, 3), 5): wz3 = sky_points(sq(asq, 3), 6)
  260.         sy0 = sq(asq, 6): sx0 = sq(asq, 4): sy1 = sq(asq, 7): sx1 = sq(asq, 4): sy2 = sq(asq, 6): sx2 = sq(asq, 5): sy3 = sq(asq, 7): sx3 = sq(asq, 5)
  261.         _MAPTRIANGLE (sx0, sy0)-(sx1, sy1)-(sx2, sy2), sky_image TO(wx0, wy0, wz0)-(wx1, wy1, wz1)-(wx2, wy2, wz2), , _SMOOTH
  262.         _MAPTRIANGLE (sx3, sy3)-(sx1, sy1)-(sx2, sy2), sky_image TO(wx3, wy3, wz3)-(wx1, wy1, wz1)-(wx2, wy2, wz2), , _SMOOTH
  263.     NEXT asq
  264.  
  265.     'calculating position and textures
  266.     clmn(0, 0) = 0 'reset column counter
  267.     FOR map_x = 0 TO map_resolution - 1: px = -map_dimxy / 2 + map_dimxy / map_resolution * (map_x - (me(0) - INT(me(0))))
  268.         FOR map_y = 0 TO map_resolution - 1: IF map(map_x, map_y, 9) = 0 THEN _CONTINUE
  269.             py = -map_dimxy / 2 + map_dimxy / map_resolution * (map_y - (me(1) - INT(me(1))))
  270.             read_mapx = INT((map_x + perl_setx) MOD map_resolution): read_mapy = INT((map_y + perl_sety) MOD map_resolution): map_z = map(read_mapx, read_mapy, 0)
  271.             map(map_x, map_y, 7) = 0: pz2 = map_dimz * map_z - me(2): rotate px, py, pz2, 1: IF see_point = 0 THEN _CONTINUE
  272.             map(map_x, map_y, 1) = rotating(0): map(map_x, map_y, 2) = rotating(1): map(map_x, map_y, 3) = rotating(2): map(map_x, map_y, 7) = 1
  273.             map(map_x, map_y, 5) = INT(text_height_scale * map_z): IF map(map_x, map_y, 5) > text_height_scale - 1 THEN map(map_x, map_y, 5) = text_height_scale - 1
  274.             IF map(map_x, map_y, 5) < 0 THEN map(map_x, map_y, 5) = 0
  275.             IF map(read_mapx, read_mapy, 6) THEN clmn(clmn(0, 0) + 1, 2) = map(map_x, map_y, 8): clmn(clmn(0, 0) + 1, 0) = px: clmn(clmn(0, 0) + 1, 1) = py: clmn(0, 0) = clmn(0, 0) + 1
  276.     NEXT map_y, map_x
  277.  
  278.  
  279.     'do maptriangle from squares !
  280.     FOR map_x = 0 TO map_resolution - 2: FOR map_y = 0 TO map_resolution - 2
  281.             IF (map(map_x, map_y, 7) AND map(map_x + 1, map_y, 7) AND map(map_x, map_y + 1, 7) AND map(map_x + 1, map_y + 1, 7)) = 0 THEN _CONTINUE
  282.             m0x = map(map_x, map_y, 1): m0y = map(map_x, map_y, 2): m0z = map(map_x, map_y, 3)
  283.             m1x = map(map_x + 1, map_y, 1): m1y = map(map_x + 1, map_y, 2): m1z = map(map_x + 1, map_y, 3)
  284.             m2x = map(map_x, map_y + 1, 1): m2y = map(map_x, map_y + 1, 2): m2z = map(map_x, map_y + 1, 3)
  285.             m3x = map(map_x + 1, map_y + 1, 1): m3y = map(map_x + 1, map_y + 1, 2): m3z = map(map_x + 1, map_y + 1, 3)
  286.             atexture = texture(map(map_x, map_y, 8), 0)
  287.  
  288.             sx1 = (perl_setx + map_x) * text_multi: sy1 = (perl_sety + map_y) * text_multi: sx2 = sx1 + text_multi: sy2 = sy1 + text_multi
  289.  
  290.             _MAPTRIANGLE (sx1, sy1)-(sx2, sy1)-(sx1, sy2), atexture TO(m0x, m0y, m0z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  291.             _MAPTRIANGLE (sx2, sy2)-(sx2, sy1)-(sx1, sy2), atexture TO(m3x, m3y, m3z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  292.     NEXT map_y, map_x
  293.  
  294.     'draw columns
  295.     ac_ang = 11: column_height = 800: column_rot = column_rot + 1: FOR ac = 0 TO clmn(0, 0) - 1: FOR t = 0 TO ac_ang - 1
  296.             temp = (360 / ac_ang * t + column_rot) * pip180: px = clmn(ac + 1, 0) + SIN(temp) * clmn_rad: py = clmn(ac + 1, 1) + COS(temp) * clmn_rad
  297.             pz2 = 300 - me(2): rotate px, py, pz2, 0: ac(t, 0, 0) = rotating(0): ac(t, 1, 0) = rotating(1): ac(t, 2, 0) = rotating(2)
  298.         pz2 = -150 - me(2): rotate px, py, pz2, 0: ac(t, 0, 1) = rotating(0): ac(t, 1, 1) = rotating(1): ac(t, 2, 1) = rotating(2): NEXT t
  299.  
  300.         FOR t = 0 TO ac_ang - 1: t2 = (t + 1) MOD ac_ang
  301.             m0x = ac(t, 0, 0): m0y = ac(t, 1, 0): m0z = ac(t, 2, 0): m1x = ac(t2, 0, 0): m1y = ac(t2, 1, 0): m1z = ac(t2, 2, 0)
  302.             m2x = ac(t, 0, 1): m2y = ac(t, 1, 1): m2z = ac(t, 2, 1): m3x = ac(t2, 0, 1): m3y = ac(t2, 1, 1): m3z = ac(t2, 2, 1)
  303.             atexture = texture(clmn(ac + 1, 2), 0): dd = 4: pm = 40 * dd: pm2 = 310 * dd: sx1 = pm * t: sy1 = pm2: sx2 = sx1 + pm: sy2 = sy1 + pm2
  304.             _MAPTRIANGLE (sx1, sy1)-(sx2, sy1)-(sx1, sy2), atexture TO(m0x, m0y, m0z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  305.             _MAPTRIANGLE (sx2, sy2)-(sx2, sy1)-(sx1, sy2), atexture TO(m3x, m3y, m3z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  306.  
  307.     NEXT t, ac
  308.  
  309.  
  310.  
  311.     'target draw
  312.     dis = SQR((targ(0) - me(0)) ^ 2 + (targ(1) - me(1)) ^ 2): _PRINTSTRING (0, 20), "target distance:" + STR$(dis)
  313.  
  314.     IF dis < map_resolution / 2 * 1.5 THEN
  315.         ee = map_dimxy / map_resolution: targ_size = 50: rotate (targ(0) - me(0)) * ee, (targ(1) - me(1)) * ee, (targ(2) - me(2)) * 1, 0
  316.         m0x = rotating(0) - targ_size: m0y = rotating(1) - targ_size: m0z = rotating(2): m1x = rotating(0) + targ_size: m1y = rotating(1) - targ_size: m1z = rotating(2)
  317.         m2x = rotating(0) - targ_size: m2y = rotating(1) + targ_size: m2z = rotating(2): m3x = rotating(0) + targ_size: m3y = rotating(1) + targ_size: m3z = rotating(2)
  318.         _MAPTRIANGLE (0, 500 - 1)-(500 - 1, 500 - 1)-(0, 0), targ_text TO(m0x, m0y, m0z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  319.         _MAPTRIANGLE (500 - 1, 0)-(500 - 1, 500 - 1)-(0, 0), targ_text TO(m3x, m3y, m3z)-(m1x, m1y, m1z)-(m2x, m2y, m2z)
  320.     END IF
  321.  
  322.     IF new_target_signal AND INT(RND(1) * 2) THEN _PRINTSTRING (600, 20), "NEW TARGET !!!!!"
  323.     new_target_signal = new_target_signal - 1: IF new_target_signal < 0 THEN new_target_signal = 0
  324.  
  325.  
  326.  
  327.     IF dis < 4 OR bill$ = "l" THEN GOSUB new_target
  328.  
  329.  
  330.     'draw radar
  331.     m0x = win_marg: m1x = m0x + rad_size: m0y = mony - rad_size - win_marg: m1y = m0y + rad_size
  332.     _MAPTRIANGLE (0, 0)-(rad_ts - 1, 0)-(0, rad_ts - 1), rad_text TO(m0x, m0y)-(m1x, m0y)-(m0x, m1y), , _SMOOTH
  333.     _MAPTRIANGLE (rad_ts - 1, rad_ts - 1)-(rad_ts - 1, 0)-(0, rad_ts - 1), rad_text TO(m1x, m1y)-(m1x, m0y)-(m0x, m1y), , _SMOOTH
  334.  
  335.     'draw objects in radar
  336.     rad_obj_multi = .8: rad_obj_limit = rad_size / 2 * .9: angle = me(5) + (degree(targ(1) - me(1), targ(0) - me(0)) - 90) * pip180
  337.     dis = SQR((targ(0) - me(0)) ^ 2 + (targ(1) - me(1)) ^ 2) * rad_obj_multi: IF dis > rad_obj_limit THEN dis = rad_obj_limit
  338.     x = SIN(angle) * dis + win_marg + rad_size / 2: y = mony - win_marg - rad_size / 2 + COS(angle) * dis: ros = 10
  339.     _MAPTRIANGLE (0, 0)-(rado_ts - 1, 0)-(0, rado_ts - 1), rado_text TO(x - ros, y - ros)-(x + ros, y - ros)-(x - ros, y + ros), , _SMOOTH
  340.     _MAPTRIANGLE (rado_ts - 1, rado_ts - 1)-(rado_ts - 1, 0)-(0, rado_ts - 1), rado_text TO(x + ros, y + ros)-(x + ros, y - ros)-(x - ros, y + ros), , _SMOOTH
  341.  
  342.  
  343.  
  344.  
  345.  
  346.     _DISPLAY: _PRINTSTRING (0, 20), SPACE$(160)
  347.  
  348.  
  349.  
  350. new_target: l = 200: targ(0) = map_center + l / 2 + l * RND(1): targ(1) = map_center + l / 2 + l * RND(1): targ(2) = (map_deep(targ(0), targ(1)) - .1 - targ_size / 2)
  351. new_target_signal = 160: RETURN
  352.  
  353.  
  354.  
  355.  
  356. FUNCTION noise (x, y) 'reading pseudo random buffer
  357.     x2 = INT(x): y2 = INT(y): a = INT(ABS(x2) + ABS(y2)) MOD noise_rand_c: b = ABS(x2) MOD noise_rand_c: c = noise_rand(a) + noise_rand(b): noise = c - INT(c)
  358.  
  359. FUNCTION SmoothNoise (x, y)
  360.     SELECT CASE perlin_smooth_noise_interpolation_type
  361.         CASE 0: SmoothNoise = noise(x, y)
  362.         CASE 1: corners = (noise(x - 1, y - 1) + noise(x + 1, y - 1) + noise(x - 1, y + 1) + noise(x + 1, y + 1)) / 16
  363.             sides = (noise(x - 1, y) + noise(x + 1, y) + noise(x, y - 1) + noise(x, y + 1)) / 8: center = noise(x, y) / 4: SmoothNoise = corners + sides + center
  364.  
  365. FUNCTION Perlin2D_original (x, y): total = 0: FOR t = 0 TO perlin_level - 1: frequency = 2 ^ t * perlin_multiplier: amplitude = perlin_pers ^ t
  366. total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude: NEXT t: Perlin2D_original = total: END FUNCTION
  367.  
  368. FUNCTION perlin2d (x, y): perlin2dx = mapz_multiplier * (Perlin2D_original(x, y) - mapz_min)
  369.     IF perlin2dx > perlin_flat_soil_limit_low THEN perlin2dx = perlin_flat_soil_limit_low
  370.     IF perlin2dx < perlin_flat_soil_limit_high THEN perlin2dx = perlin_flat_soil_limit_high
  371.     perlin2d = perlin2dx
  372.  
  373. FUNCTION InterpolatedNoise (x, y): integer_X = INT(x): fractional_X = x - integer_X: integer_y = INT(y): fractional_Y = y - integer_y
  374.     v1 = SmoothNoise(integer_X, integer_y): v2 = SmoothNoise(integer_X + 1, integer_y)
  375.     v3 = SmoothNoise(integer_X, integer_y + 1): v4 = SmoothNoise(integer_X + 1, integer_y + 1)
  376. i1 = Interpolate(v1, v2, fractional_X): i2 = Interpolate(v3, v4, fractional_X): InterpolatedNoise = Interpolate(i1, i2, fractional_Y): END FUNCTION
  377.  
  378. FUNCTION Interpolate (a, b, x): Interpolate = a * (1 - x) + b * x: END FUNCTION
  379.  
  380. SUB rotate (px, py, pz2, see_analysis)
  381.     px3 = px * cosrotz - py * sinrotz: py2 = px * sinrotz + py * cosrotz: py3 = py2 * cosrotx - pz2 * sinrotx: pz3 = -(py2 * sinrotx + pz2 * cosrotx)
  382.     see_point = pz3 < 200: IF see_point = 0 AND see_analysis THEN EXIT SUB
  383.     rotating(0) = -(px3 * COS(rotx_bevel) - py3 * SIN(rotx_bevel)) * map_zoom_xy: rotating(1) = -(px3 * SIN(rotx_bevel) + py3 * COS(rotx_bevel)) * map_zoom_xy
  384. rotating(2) = pz3 * map_zoom_distance: END SUB
  385.  
  386.  
  387. SUB flight_control (af, test)
  388.  
  389.     rotx = flight(af, 1): me0 = flight(af, 3): me1 = flight(af, 4): me2 = flight(af, 5): me3 = flight(af, 6): me4 = flight(af, 7): kw = ABS(flight(af, 8))
  390.     ks = ABS(flight(af, 9)): mousey = flight(af, 11): mousex = flight(af, 10): me6 = flight(af, 12): me5 = flight(af, 13): rotx_bevel3 = flight(af, 2)
  391.  
  392.     rotx = (rotx + mousex * .005) * .95: IF ABS(rotx) > (max_incli * pip180) THEN rotx = max_incli * pip180 * SGN(rotx)
  393.  
  394.     actual_speed = 1 / position_speed * SQR(me3 * me3 + me4 * me4): rotx_bevel2 = rotx * actual_speed * kw
  395.     rotx_bevel3 = rotx_bevel3 + (rotx_bevel2 - rotx_bevel3) * .05: me5 = me5 + rotx / 20: me6 = me6 + mousey / 100: lim_fy = 65: temp = me6 / pip180
  396.     IF temp > 270 + lim_fy THEN temp = 270 + lim_fy
  397.     IF temp < 270 - lim_fy THEN temp = 270 - lim_fy
  398.     me6 = temp * pip180: me2 = me2 + COS(-me6) * actual_speed * 5 * kw + 1 * ABS(ks AND actual_speed < .05) 'calculating Z
  399.     actual_deep = (map_deep(me0, me1) - .1) * map_dimz
  400.     IF me2 > actual_deep - .1 THEN me2 = actual_deep - .1 - actual_speed / 4: me3 = me3 * .9: me4 = me4 * .9: flight(af, 17) = 1 ELSE flight(af, 17) = 0
  401.     IF me2 < flight_high_max THEN me2 = flight_high_max
  402.     position_accel = .02: ww = .9999: szog_xy = me5 + rotx 'calculating XY
  403.  
  404.     new_vec_x = -SIN(szog_xy) * position_accel * kw: new_vec_y = -COS(szog_xy) * position_accel * kw: vec_x = (me3 * ww + new_vec_x): vec_y = (me4 * ww + new_vec_y)
  405.     vec_sum = SQR(vec_x * vec_x + vec_y * vec_y): IF vec_sum > position_speed THEN vec_sum = position_speed / vec_sum ELSE vec_sum = 1
  406.     me3 = vec_x * vec_sum: me4 = vec_y * vec_sum: me0 = me0 + me3: me1 = me1 + me4: IF ks THEN deacc = .96 ELSE deacc = .99: IF kw THEN deacc = 1
  407.     me3 = me3 * deacc: me4 = me4 * deacc: flight(af, 16) = 0
  408.     IF crash_to_column(me0, me1) THEN
  409.         flight(af, 16) = 1
  410.         IF test = 0 THEN me3 = -me3 * .7: me4 = -me4 * .7: DO: m0 = m0 + me3: me1 = me1 + me4: LOOP WHILE crash_to_column(me0, me1)
  411.     END IF
  412.     flight(af, 1) = rotx: flight(af, 3) = me0: flight(af, 4) = me1: flight(af, 5) = me2: flight(af, 6) = me3: flight(af, 7) = me4: flight(af, 2) = rotx_bevel3
  413.     flight(af, 12) = me6: flight(af, 13) = me5: flight(af, 15) = actual_speed
  414.  
  415.  
  416. FUNCTION map_deep (x, y): read_mapx1 = INT(x + map_resper2) MOD map_resolution: read_mapx2 = INT(x + map_resper2 + 1) MOD map_resolution
  417.     read_mapy1 = INT(y + map_resper2) MOD map_resolution: read_mapy2 = INT(y + map_resper2 + 1) MOD map_resolution
  418.     mapx1 = Interpolate(map(read_mapx1, read_mapy1, 0), map(read_mapx2, read_mapy1, 0), me(0) - INT(me(0)))
  419.     mapx2 = Interpolate(map(read_mapx1, read_mapy2, 0), map(read_mapx2, read_mapy2, 0), me(0) - INT(me(0)))
  420. map_deep = Interpolate(mapx1, mapx2, me(1) - INT(me(1))): END FUNCTION
  421.  
  422.  
  423. FUNCTION crash_to_column (x, y): pixs_column = INT(map_dimxy / map_resolution / clmn_rad) + 2
  424.     FOR tx = -pixs_column TO pixs_column: FOR ty = -pixs_column TO pixs_column
  425.             read_mapx = INT(x + map_resper2 + tx) MOD map_resolution: read_mapy = INT(y + map_resper2 + ty) MOD map_resolution
  426.             IF map(read_mapx, read_mapy, 6) THEN crash_to_column = 1: EXIT FUNCTION
  427. NEXT ty, tx: END FUNCTION
  428.  
  429. FUNCTION degree (a, b): degreex = ATN((a + .00001) / (b + .00001)) / pip180: degreex = degreex - 180 * ABS(0 > b): degreex = degreex - 360 * (degreex < 0)
  430. degree = degreex: END FUNCTION
  431.  
  432.