_TITLE "OldMoses' 3D StarField V.3 (h to toggle help menu)"
TYPE star
' define the star data type xa
AS INTEGER ' apparent x position on screen ya
AS INTEGER ' apparent y position on screen
DIM SHARED p
(starcount
) AS star
' dimension the star data array DIM vwport
AS INTEGER: vwport
= 1200 ' set the viewport setback from viewer's eye DIM hlptog
AS _BYTE: hlptog
= 0 ' help menu display toggle DIM dattog
AS _BYTE: dattog
= -1 ' data bar display toggle DIM tartog
AS _BYTE: tartog
= 0 ' target crosshair DIM lartog
AS _BYTE: lartog
= 0 ' large star toggle
scw2 = scrw / 2
sch2 = scrh / 2
PopVoid ' OldMoses said "Let there be light" and the universe was, is and ever shall be
WINDOW (-scw2
, sch2
)-(scw2
, -sch2
) ' create viewport window, Cap'n Kirk spends his days staring at this
starcount = starcount + 1 '
AddStar starcount '
starcount = starcount - 1 ' subtract stars
vp12 = vwport / 1200
pitch
= -(SIN(ych
* 0.005236) / 2) * (ych
<> 0) yaw
= -(SIN(xch
* 0.005236) / 2) * (xch
<> 0)
FOR x%
= 1 TO starcount
' iterate through all stars
IF xch
<> 0 OR ych
<> 0 THEN ' not actually a proper transformation p(x%).x = p(x%).x + p(x%).z * yaw ' slew stars for left/right turns
p(x%).y = p(x%).y + p(x%).z * pitch ' slew stars for up/down pitch
IF p
(x%
).z
> 0 THEN 'ignore those behind, change to a dot product test if a facing vector is later added p(x%).xa = p(x%).x / p(x%).z * vwport ' get relative screen position from absolute position for x & y
p(x%).ya = p(x%).y / p(x%).z * vwport
IF ABS(p
(x%
).xa
) < scw2
AND ABS(p
(x%
).ya
) < sch2
THEN 'place the star if within the viewport IF lartog
THEN ' Larger near field stars CASE 0 TO 1875 'fade to circle 16 FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
+ 5, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, map!
(dst&
, 1875, 0, 0, 255)) 'proximity star plot FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
+ 3, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, 255) 'proximity star plot CASE 1876 TO 3750 'fade to circle 8 FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
+ 3, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, map!
(dst&
, 3750, 1876, 0, 255)) 'proximity star plot FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
+ 1, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, 255) 'proximity star plot CASE 3751 TO 7500 'fade to circle 4 FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
+ 1, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, map!
(dst&
, 7500, 3751, 0, 255)) 'proximity star plot FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, 255) CASE 7501 TO 14999 'fade to circle 2 FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, map!
(dst&
, 14999, 7501, 0, 255)) 'near star plot PSET (p
(x%
).xa
, p
(x%
).ya
), _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, 255) CASE IS > 15000 'point fade in PSET (p
(x%
).xa
, p
(x%
).ya
), _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, map!
(dst&
, 30000, 15000, 0, 255)) 'far star plot CASE 0 TO 3999 ' Smaller near field, using map algorithm FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
+ 1, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, map!
(dst&
, 3999, 0, 0, 255)) 'proximity star plot FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, 255) FCirc p
(x%
).xa
, p
(x%
).ya
, bsrad
, _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, map!
(dst&
, 14999, 4000, 0, 255)) 'near star plot PSET (p
(x%
).xa
, p
(x%
).ya
), _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, 255) PSET (p
(x%
).xa
, p
(x%
).ya
), _RGBA32(p
(x%
).r
, p
(x%
).g
, p
(x%
).b
, map!
(dst&
, 30000, 15000, 0, 255)) 'far star plot END IF ' end: large star toggle test END IF ' end: stars within viewport test END IF ' end: stars in front of viewer test
p(x%).z = p(x%).z - speed ' move the star relative to the viewer
IF ABS(p
(x%
).z
) > 30000 THEN ' recycle stars that leave the limits ReplaceStar x%
, p
(x%
).z
- (30000 * -SGN(speed
))
xch = 0: ych = 0
IF dattog
THEN Footer speed
, vp12
_LIMIT 1000 ' smooth out the action
SUB PopVoid
' Do an initial population of stars
FOR x%
= 1 TO starcount
' place a 'starcount' # of stars randomly in a 3D space p
(x%
).x
= INT(RND * 60000) - 30000 p
(x%
).y
= INT(RND * 60000) - 30000 p
(x%
).z
= INT(RND * 60000) - 30000
t%
= INT(RND * 110) - 55 ' star spectrum/color p(x%).r = 200 + t%: p(x%).b = 200 - t%
p(x%).r = 200 - t%: p(x%).b = 200 + t%
p(x%).g = 200 + gi% ^ 2
p(x%).g = 200
p
(var
).x
= INT(RND * 60000) - 30000 ' New x,y,z but keep old color for simplicity sake p
(var
).y
= INT(RND * 60000) - 30000 p(var).z = p(var).z + insert
'Steve's circle fill
RError = -R
X = R
Y = 0
LINE (CX
- X
, CY
)-(CX
+ X
, CY
), C
, BF
RError = RError + Y * 2 + 1
LINE (CX
- Y
, CY
- X
)-(CX
+ Y
, CY
- X
), C
, BF
LINE (CX
- Y
, CY
+ X
)-(CX
+ Y
, CY
+ X
), C
, BF
X = X - 1
RError = RError - X * 2
Y = Y + 1
LINE (CX
- X
, CY
- Y
)-(CX
+ X
, CY
- Y
), C
, BF
LINE (CX
- X
, CY
+ Y
)-(CX
+ X
, CY
+ Y
), C
, BF
p
(x
).x
= INT(RND * 60000) - 30000 p
(x
).y
= INT(RND * 60000) - 30000 p(x).z = 30000
p(x).z = -30000
p(x).r = 200 + t%: p(x).b = 200 - t%
p(x).r = 200 - t%: p(x).b = 200 + t%
p(x).g = 200 + gi% ^ 2
p(x).g = 200
mi = (sch2) - (15 * 16 / 2) ' change ...(x * 16 / 2) to x= number of items in menu
_PRINTSTRING (scw2
- 150, mi
+ 32), "<left arrow> turn left", 0 _PRINTSTRING (scw2
- 150, mi
+ 48), "<right arrow> turn right", 0 _PRINTSTRING (scw2
- 150, mi
+ 64), "<up arrow> pitch up", 0 _PRINTSTRING (scw2
- 150, mi
+ 80), "<down arrow> pitch down", 0 _PRINTSTRING (scw2
- 150, mi
+ 144), "<s> subtract stars", 0 _PRINTSTRING (scw2
- 150, mi
+ 160), "<h> toggle this list on/off", 0 _PRINTSTRING (scw2
- 150, mi
+ 176), "<d> toggle data bar", 0 _PRINTSTRING (scw2
- 150, mi
+ 192), "<t> toggle crosshairs", 0 _PRINTSTRING (scw2
- 150, mi
+ 208), "<l> toggle large stars on/off", 0
_PRINTSTRING (scrw
- 100, scrh
- 60), "Mag. x" + STR$(var2
), 0 ' magnification factor
LINE (-50, -50)-(-10, -10), &H7FFF0000 LINE (50, -50)-(10, -10), &H7FFF0000 LINE (50, 50)-(10, 10), &H7FFF0000 LINE (-50, 50)-(-10, 10), &H7FFF0000
FUNCTION map!
(value!
, minRange!
, maxRange!
, newMinRange!
, newMaxRange!
)
'called from: various
map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!