Jump to content

Starfield screensaver


Lazycat
 Share

Recommended Posts

My vacation is coming to end, I'm was bored and made something totally useless for fun, so this is more scrap then script :whistle: Anyway, here the simple screensaver that simulate old DosNavigator's (?) starfield screensaver. It's damn slow, but fully functional, even with config window. Compile it, rename to *.scr and put into windows or system folder.

Only for beta, sorry.

Au3stars.au3

Link to comment
Share on other sites

Neat!

I took the Int() wrapper off the $Stars[$i][2] assignment, to give it a smoother flow.

Link to comment
Share on other sites

Nice one Lazycat! :dance:

<{POST_SNAPBACK}>

I truely see a Game in this somewhere, also was wondering if

you had plans on doing a forward view star field

works great on my laptop.

now how to incorperate celestia and autoit to make a truely

awesome space sim :whistle:

Link to comment
Share on other sites

OK, I've been fiddling with this thing trying to make it look cooler and more 3d, and finally broke down and wrote some 3d and pseudo-3d routines. I also used onevent mode to try to speed it up a bit. (but haven't done an actual benchmark to see if I was successful or not)

I haven't touched the config panel, so to adjust the new stuff just change the constants at the beginning. Use small numbers, because the 3d universe coordinate system is only -1 to 1 in all dimensions. Also Speed and Bias have no relavence anymore.

Anyway, have at it:

#include <GUIConstants.au3>

Const $gFocalDistance = 1;Focal Distance affects the field of view.
;If you want to find FOV in degrees then:
;FOV = ArcTan(1/$gFocalDistance) * 114.59155902616464175359630962821
;If you want to set FOV in degrees then:
;FocalDistance = 1 / Tan(FOV * 114.59155902616464175359630962821)

Const $gMaxTurnRate = 3;maximum turn rate in degrees
Const $gMouseSensativity = 3;how far you have to move the mouse to trigger a screen saver cancel

Dim $gDone = 0, $gMouse

Func coord3dto2d($x, $y, $z)
    Local $return[2]
    $Return[0] = ($gFocalDistance * $x) / ($gFocalDistance + $z)
    $Return[1] = ($gFocalDistance * $y) / ($gFocalDistance + $z)
    Return $return
EndFunc

Opt("ColorMode", 1)
$gSpeed   = IniRead("starfield.ini", "Main", "Speed", 50)
$gNumStars   = IniRead("starfield.ini", "Main", "NumStars", 32)
$gStarSize   = IniRead("starfield.ini", "Main", "StarSize", 2)
$gStarBias   = IniRead("starfield.ini", "Main", "StarBias", 4)
$gStarColor  = IniRead("starfield.ini", "Main", "StarColor", 0xFFFFFF)
$gFieldColor = IniRead("starfield.ini", "Main", "FieldColor", 0)
$gRandColor  = IniRead("starfield.ini", "Main", "RandomColor", 1)

If StringInStr($CmdLineRaw, "/S") Then
    SaverWindow(@DesktopWidth, @DesktopHeight, 0, 0)
ElseIf StringInStr($CmdLineRaw, "/P") Then
    Exit
Else
    ConfigWindow()
Endif

Func StarsStepForward(ByRef $stars, $step = .01)
    For $i = 0 to UBound($stars, 1) - 1
        $stars[$i][2] -= $Step
        If $stars[$i][2] < -1 Then
            $stars[$i][0] = Random(-1,1);x
            $stars[$i][1] = Random(-1,1);y
            $stars[$i][2] += 2;z
        EndIf
        If $stars[$i][2] > 1 Then
            $stars[$i][0] = Random(-1,1);x
            $stars[$i][1] = Random(-1,1);y
            $stars[$i][2] -= 2;z
        EndIf
    Next
EndFunc

Func StarsRotateX(ByRef $Stars, $Degrees = 5)
    Local $Theta, $sin, $cos, $i, $x, $y
    $Theta = $Degrees / 57.295779513082320876798154814105
    $sin = Sin($Theta)
    $cos = Cos($Theta)
    For $i = 0 to UBound($stars, 1) - 1
        $x = $Cos * $Stars[$i][2] - $Sin * $Stars[$i][1]
        $y = $cos * $Stars[$i][1] + $Sin * $Stars[$i][2]
        $Stars[$i][2] = $x
        $Stars[$i][1] = $y
    Next
EndFunc

Func StarsRotateY(ByRef $Stars, $Degrees = 5)
    Local $Theta, $sin, $cos, $i, $x, $y
    $Theta = $Degrees / 57.295779513082320876798154814105
    $sin = Sin($Theta)
    $cos = Cos($Theta)
    For $i = 0 to UBound($stars, 1) - 1
        $x = $Cos * $Stars[$i][0] - $Sin * $Stars[$i][2]
        $y = $cos * $Stars[$i][2] + $Sin * $Stars[$i][0]
        $Stars[$i][0] = $x
        $Stars[$i][2] = $y
    Next
EndFunc

Func StarsRotateZ(ByRef $Stars, $Degrees = 5)
    Local $Theta, $sin, $cos, $i, $x, $y
    $Theta = $Degrees / 57.295779513082320876798154814105
    $sin = Sin($Theta)
    $cos = Cos($Theta)
    For $i = 0 to UBound($stars, 1) - 1
        $x = $Cos * $Stars[$i][0] - $Sin * $Stars[$i][1]
        $y = $cos * $Stars[$i][1] + $Sin * $Stars[$i][0]
        $Stars[$i][0] = $x
        $Stars[$i][1] = $y
    Next
EndFunc

Func SaverWindow($nWidth, $nHeight, $nLeft, $nTop, $hParent = 0)
;Set up GUI window
    $hGUI = GUICreate("", $nWidth, $nHeight, $nLeft, $nTop, $WS_POPUPWINDOW, $WS_EX_TOPMOST, $hParent)
    GUISetBkColor($gFieldColor)
;Create Stars
    Local $stars[$gNumStars][4]
    For $i = 0 To $gNumStars - 1
    ;the coordinate universe is from -1 to 1 in 3 dimensions
        $stars[$i][0] = Random(-1,1);x
        $stars[$i][1] = Random(-1,1);y
        $stars[$i][2] = Random(-1,1);z
        $stars[$i][3] = GUICtrlCreateLabel(" ", -10, -10, $gStarSize, $gStarSize)
        If $gRandColor = 1 Then
            GUICtrlSetBkColor(-1, Int(Random(0, 0xFFFFFF)))
        Else
            GUICtrlSetBkColor(-1, $gStarColor)
        Endif
    Next

    GUISetState()
    
    Local $movement, $timeleft, $TurnRate, $LastGuiMode
    $gMouse=MouseGetPos()
    $LastGuiMode = Opt("GUIOnEventMode", 1)
    $gDone = 0
    GUISetOnEvent($GUI_EVENT_MOUSEMOVE, 'SetDone')
    While not $gDone
    ;$TimeLeft is a count-down timer for the next movement type
        $timeleft -= 1
        If $timeleft < 1 Then
            $timeleft = Random(20,60,1)
            $movement = Random(0,3,1)
            If Random(0,1,1) Then $movement = $movement * -1
            $TurnRate = 0
        EndIf
    ;pseudo-smooth transitions
        If $TurnRate < $gMaxTurnRate Then $TurnRate += 1
        If $TurnRate > $TimeLeft Then $TurnRate = $TimeLeft
    ;Make the turn
        Select
            Case $movement = 1
                StarsRotateX($Stars, $TurnRate)
            Case $movement = -1
                StarsRotateX($Stars, -$TurnRate)
            Case $movement = 2
                StarsRotateY($Stars, $TurnRate)
            Case $movement = -2
                StarsRotateY($Stars, -$TurnRate)
            Case $movement = 3
                StarsRotateZ($Stars, $TurnRate)
            Case $movement = -3
                StarsRotateZ($Stars, -$TurnRate)
        EndSelect
    ;move forward
        StarsStepForward($Stars, .05)
    ;draw the stars
        For $i = 0 To $gNumStars - 1
            If $Stars[$i][2] > 0 Then
            ;find 2d coordinates for the star and move it accordingly
                $coord = Coord3dto2d($stars[$i][0], $stars[$i][1], $stars[$i][2])
                $Coord[0] = ($Coord[0] + 1) * $nWidth / 2 + $nLeft
                $Coord[1] = ($Coord[1] + 1) * $nHeight / 2 + $nTop
                GUICtrlSetPos($stars[$i][3], $Coord[0], $Coord[1])
            Else
            ;move the star outside the viewable range
                GUICtrlSetPos($stars[$i][3], -10, -10)
            EndIf
        Next
    WEnd
    Opt("GUIOnEventMode", $LastGuiMode)
    GUIDelete($hGUI)
EndFunc

Func SetDone()
    Local $mouse = MouseGetPos()
    If abs($mouse[0] - $gmouse[0]) > $gMouseSensativity Or abs($mouse[1] - $gmouse[1]) > $gMouseSensativity Then
        $gDone = 1
    Else
        $gMouse = $Mouse
    EndIf
EndFunc

Func ConfigWindow()
    $hConfigGUI = GuiCreate("Stars Saver Config", 358, 148, 302,218 ,BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
    $hOk      = GuiCtrlCreateButton("OK", 274, 84, 80, 24)
    $hPreview = GuiCtrlCreateButton("Preview", 140, 118, 80, 25)
    $hCancel  = GuiCtrlCreateButton("Cancel", 274, 118, 80, 25)
    GuiCtrlCreateGroup("Stars", 3, 0, 129, 145)
    GuiCtrlCreateGroup("Color", 136, 0, 220, 80)
    GuiCtrlCreateLabel("Star count", 8, 24, 49, 13)
    GuiCtrlCreateLabel("Speed", 8, 56, 31, 13)
    GuiCtrlCreateLabel("Bias", 8, 88, 20, 13)
    GuiCtrlCreateLabel("Star size", 8, 120, 40, 13)
    $SpinEditInput1=GuiCtrlCreateInput($gNumStars, 64, 16, 49, 22)
    $up = GUICtrlCreateUpdown(-1)
    GUICtrlSetLimit(-1, 256, 1)
    $SpinEditInput2=GuiCtrlCreateInput($gSpeed, 64, 48, 49, 22)
    GUICtrlCreateUpdown(-1)
    GUICtrlSetLimit(-1, 50, 1)
    $SpinEditInput3=GuiCtrlCreateInput($gStarBias, 64, 80, 49, 22)
    GUICtrlCreateUpdown(-1)
    GUICtrlSetLimit(-1, 32, 2)
    $SpinEditInput4=GuiCtrlCreateInput($gStarSize, 64, 112, 49, 22)
    GUICtrlCreateUpdown(-1)
    GUICtrlSetLimit(-1, 3, 1)
    GUICtrlCreateLabel("Stars color", 148, 20)
    $hStarsColorLbl = GUICtrlCreateLabel(" ", 208, 16, 40, 20)
    GUICtrlSetBkColor(-1, $gStarColor)
    $hStarsColorBtn = GUICtrlCreateButton("...", 254, 16, 30, 20)
    $hRndCheck = GUICtrlCreateCheckbox("Random", 290, 15)
    GUICtrlSetState(-1, $gRandColor)
    
    GUICtrlCreateLabel("Field color", 148, 50)
    $hFieldColorLbl = GUICtrlCreateLabel(" ", 208, 46, 40, 20)
    GUICtrlSetBkColor(-1, $gFieldColor)
    $hFieldColorBtn = GUICtrlCreateButton("...", 254, 46, 30, 20)

    If $gRandColor = 1 Then
        GUICtrlSetBkColor($hStarsColorLbl, 0xCCCCCC)
        GUICtrlSetState($hStarsColorBtn, $GUI_DISABLE)
    Endif

    GuiSetState()
    While 1
        $msg = GuiGetMsg()
        Select
            Case $msg = $hOk or $msg = $hPreview
                $gNumStars = GUICtrlRead($SpinEditInput1)
                $gSpeed = GUICtrlRead($SpinEditInput2)
                $gStarBias = GUICtrlRead($SpinEditInput3)
                $gStarSize = GUICtrlRead($SpinEditInput4)
                If $msg = $hPreview Then
                    SaverWindow(640, 480, -1, -1, $hConfigGUI)
                Else
                    IniWrite("starfield.ini", "Main", "Speed", $gSpeed)
                    IniWrite("starfield.ini", "Main", "NumStars", $gNumStars)
                    IniWrite("starfield.ini", "Main", "StarSize", $gStarSize)
                    IniWrite("starfield.ini", "Main", "StarBias", $gStarBias)
                    IniWrite("starfield.ini", "Main", "StarColor", $gStarColor)
                    IniWrite("starfield.ini", "Main", "FieldColor", $gFieldColor)
                    IniWrite("starfield.ini", "Main", "RandomColor", $gRandColor)
                    Exit
                Endif
            Case $msg = $hStarsColorBtn
                 ChooseColor($hConfigGUI, $gStarColor)
                 GUICtrlSetBkColor($hStarsColorLbl, $gStarColor)
            Case $msg = $hFieldColorBtn
                 ChooseColor($hConfigGUI, $gFieldColor)
                 GUICtrlSetBkColor($hFieldColorLbl, $gFieldColor)
            Case $msg = $hRndCheck
                $gRandColor = GUICtrlRead($hRndCheck)
                If BitAnd($gRandColor, 1) Then
                    GUICtrlSetBkColor($hStarsColorLbl, 0xCCCCCC)
                    GUICtrlSetState($hStarsColorBtn, $GUI_DISABLE)
                Else
                    GUICtrlSetBkColor($hStarsColorLbl, $gStarColor)
                    GUICtrlSetState($hStarsColorBtn, $GUI_ENABLE)
                Endif
            Case $msg = $GUI_EVENT_CLOSE or $msg = $hCancel
                ExitLoop
        EndSelect
    WEnd
EndFunc

Func ChooseColor($hWnd, ByRef $nColor)
    $cp = DllStructCreate("dword[16]")
    $p = DllStructCreate("dword;dword;dword;dword;dword;dword;dword;dword;dword")
    DllStructSetData($p, 1, DllStructGetSize($p))
    DllStructSetData($p, 2, $hWnd)
    DllStructSetData($p, 4, $nColor)
    DllStructSetData($p, 5, DllStructGetPtr($cp))
    DllStructSetData($p, 6, 2 + 1)
    $ret = DllCall("comdlg32.dll", "long", "ChooseColorA", "ptr", DllStructGetPtr($p))
    If IsArray($ret) and $ret[0] <> 0 Then $nColor = DllStructGetData($p, 4)
    DllStructDelete($p)
    DllStructDelete($cp)
EndFunc
Link to comment
Share on other sites

OK, I've been fiddling with this thing trying to make it look cooler and more 3d, and finally broke down and wrote some 3d and pseudo-3d routines.  I also used onevent mode to try to speed it up a bit.  (but haven't done an actual benchmark to see if I was successful or not)

I haven't touched the config panel, so to adjust the new stuff just change the constants at the beginning.  Use small numbers, because the 3d universe coordinate system is only -1 to 1 in all dimensions.  Also Speed and Bias have no relavence anymore.

Anyway, have at it:

<{POST_SNAPBACK}>

Wow, awesome. That's very cool, too bad it gets so slow once you add a lot of stars though. I wonder, would it be possible to have this running with the same visual effect, but faster, if you used that dll function.. uh.. SetPixel? I don't know how much better it might work since you'd be calling the dll all the time, but it might be easier on the CPU than having 100 seperate controls that you're trying to move around.

*Edit: Of course, you'd have to "undraw" all the stars manually.

Edited by Saunders
Link to comment
Share on other sites

OK, I've been fiddling with this thing trying to make it look cooler and more 3d, and finally broke down and wrote some 3d and pseudo-3d routines. I also used onevent mode to try to speed it up a bit. (but haven't done an actual benchmark to see if I was successful or not)

I haven't touched the config panel, so to adjust the new stuff just change the constants at the beginning. Use small numbers, because the 3d universe coordinate system is only -1 to 1 in all dimensions. Also Speed and Bias have no relavence anymore.

Cool! I'm surprised where this "just for fun" project come :whistle:

Link to comment
Share on other sites

Wow, awesome. That's very cool, too bad it gets so slow once you add a lot of stars though. I wonder, would it be possible to have this running with the same visual effect, but faster, if you used that dll function.. uh.. SetPixel? I don't know how much better it might work since you'd be calling the dll all the time, but it might be easier on the CPU than having 100 seperate controls that you're trying to move around.

*Edit: Of course, you'd have to "undraw" all the stars manually.

<{POST_SNAPBACK}>

Yeah, I'm sure I could do that. I've never done Dllcalls before, but I think if you do a DllOpen() it keeps the DLL open so that you don't have to open it each time you want to make a call - this should make it faster? Again, never done this, just going on things I've overhead in this forum. And I guess if I really wanted to I could tap into Direct3d DLLs and do this properly... :whistle:

I think it's still cool to use labels, because my next thing is to replace the labels with bitmaps or something, of the autoit logo for example, and then scale them based on distance, and you now have a screensaver like the old "Flying Windows" screensaver. Maybe this could evolve into the first autoit screensaver! Too bad it's 100% CPU...

Link to comment
Share on other sites

That is truly awesome blindwig. I envy your trig skills!

<{POST_SNAPBACK}>

When I started doing 3d graphics (late 80s - mid 90s) there was no hardware 3d acceleration, nor was there any nice free 3d libraries. If you wanted 3d, trig was not optional - it was required! :whistle:

I actually wrote (from scratch, using only Turbo Pascal 5.5) a 3d modelling program to create 3d object to use in other programs. I wasn't great or commercial quality or anythinig, but I learn alot about math when making it (completely from scratch - every pixel on the screen I put there - calculated position and color and everything else).

Here's 2 images I created with it:

http://www.ratzlaff.org/mike/pictures/19970200-02.gif

http://www.ratzlaff.org/mike/thumbs/castle2-a1s.gif

Crude and low-res, but like I said it was more of a learning experience than anything else.

Link to comment
Share on other sites

When I started doing 3d graphics (late 80s - mid 90s) there was no hardware 3d acceleration, nor was there any nice free 3d libraries.  If you wanted 3d, trig was not optional - it was required! :dance:

I actually wrote (from scratch, using only Turbo Pascal 5.5) a 3d modelling program to create 3d object to use in other programs.  I wasn't great or commercial quality or anythinig, but I learn alot about math when making it (completely from scratch - every pixel on the screen I put there - calculated position and color and everything else).

Here's 2 images I created with it:

http://www.ratzlaff.org/mike/pictures/19970200-02.gif

http://www.ratzlaff.org/mike/thumbs/castle2-a1s.gif

Crude and low-res, but like I said it was more of a learning experience than anything else.

<{POST_SNAPBACK}>

Interesting. Especially the lighting with the castle one. :whistle:
Link to comment
Share on other sites

  • 8 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...