So I've been tinkering with a fluid dynamics screensaver for a number of days now. I just love just sitting and watching it and I think other
people I know might enjoy it too. I want to release it as a screensaver.
I know you can simply change .exe to .scr and it will work as a screensaver. But it doesn't work flawlessly; it doesn't preview properly
in the windows screensaver selection screen.
Is there a way to turn this exe into a proper screensaver executable file? And can I give the file a proper icon? A blank window for an icon
looks very unprofessional.
I encourage you guys to try it and tell me what you think. Here is an exe
http://www.andysuderman.com/1/AndysGelblobScreensaver.exe
and here is the code:
people I know might enjoy it too. I want to release it as a screensaver.
I know you can simply change .exe to .scr and it will work as a screensaver. But it doesn't work flawlessly; it doesn't preview properly
in the windows screensaver selection screen.
Is there a way to turn this exe into a proper screensaver executable file? And can I give the file a proper icon? A blank window for an icon
looks very unprofessional.
I encourage you guys to try it and tell me what you think. Here is an exe
http://www.andysuderman.com/1/AndysGelblobScreensaver.exe
and here is the code:
SuperStrict AppTitle = "Move mouse to Exit" Global particleNum:Int = 6900 SeedRnd MilliSecs() Graphics 800,600, 32 Global debug:Int = False Global poof:Timage = drawpoof() Global colourVolitility:Int = 2 Global initialWaited:Int = False Type vectorType Field x:Float, y:Float EndType Type lazyParticleSpyType 'This code follows a single particle(#10) around and checks if it is staying still for too long. 'If it is, an explosion is created at the location of the spy particle. This makes the dormant blobs 'explode sometimes, which looks cool. Field movementPoints:Int Method update() If particles[10].x1< 1 And particles[10].y1<1 Then movementPoints:-1 Else movementPoints:+1 If movementPoints>100 Then movementPoints = 100 EndIf If movementPoints<0 Then explode() EndMethod Method explode() Local angle:Int, power:Float For Local a:Int = 0 To particleNum If within(particles[10].x, particles[10].y, particles[a].x, particles[a].y, 40, 40) Then angle = Rand(360) power = RndFloat()*10 If Rand(4)=2 Then power:*2 particles[a].x1=Sin(angle)*power particles[a].y1=Cos(angle)*power EndIf Next movementPoints = 100 particles[10].x:+400 If particles[10].x>800 Then particles[10].x:-800 EndMethod Method New() movementPoints = 180 EndMethod EndType Global lazyParticleSpy:lazyParticleSpyType = New lazyParticleSpyType Type gridType Field show:Int Field width:Int = 800, height:Int = 600 Field resolution:Int = 30 Field xPoints:Int = width/resolution+3 Field yPoints:Int = height/resolution+2 Field vector:vectorType[xPoints+1,yPoints+1] Field xCenter:Int = 400-width*.5, yCenter:Int = 300-height*.5 Method New() For Local yy:Int = 0 To yPoints For Local xx:Int = 0 To xPoints vector[xx,yy] = New vectorType Next Next EndMethod Method calmDown() For Local y:Int = 0 To yPoints For Local x:Int = 0 To xPoints grid.vector[x,y].x:+(RndFloat()-.5)*.02 grid.vector[x,y].y:+(RndFloat()-.5)*.02 grid.vector[x,y].x:*.999 grid.vector[x,y].y:*.999 Next Next EndMethod Method speedLimit() For Local yy:Int = 0 To yPoints For Local xx:Int = 0 To xPoints If Abs(vector[xx, yy].x) > 9 vector[xx, yy].x:*.6 If Abs(vector[xx, yy].y) > 9 vector[xx, yy].y:*.6 Next Next EndMethod Method circles(event:Int=2) Local angle:Int, centerXpixels:Int = 400, centerYpixels:Int = 300, radius:Int = 300 Local xGrid:Int, yGrid:Int, centerXgrid:Int, centerYGrid:Int, r:Int, times:Int = 1 Select event Case 1 centerXPixels = Rand(800) centerYPixels = Rand(600) Case 2 times = 20 centerXPixels = Rand(800) centerYPixels = Rand(600) radius = 90+Rand(140) Default 'change nothing. Keep default values EndSelect For Local b:Int = 1 To times r = 0 Repeat angle = 0 Repeat xGrid = (centerXpixels+r*Sin(angle))/resolution yGrid = (centerYpixels+r*Cos(angle))/resolution If xGrid > xPoints Then xGrid:-xPoints If yGrid > yPoints Then yGrid:-yPoints If xGrid < 0 Then xGrid:+xPoints If yGrid < 0 Then yGrid:+yPoints grid.vector[xGrid,yGrid].x = Sin(angle+90) grid.vector[xGrid,yGrid].y = Cos(angle+90) angle:+10 Until angle>360 r:+10 Until r > radius angle = 0 Repeat xGrid = (centerXpixels+radius*Sin(angle))/resolution yGrid = (centerYpixels+radius*Cos(angle))/resolution If xGrid > xPoints Then xGrid:-xPoints If yGrid > yPoints Then yGrid:-yPoints If xGrid < 0 Then xGrid:+xPoints If yGrid < 0 Then yGrid:+yPoints grid.vector[xGrid,yGrid].x = Sin(angle+140)*2 grid.vector[xGrid,yGrid].y = Cos(angle+140)*2 angle:+10 Until angle> 360 centerXPixels = Rand(800) centerYPixels = Rand(600) radius = 90+Rand(140) Next EndMethod Method waterSmear(whichOne:Int =0) If Not whichone Then whichone = Rand(2) Select whichOne Case 1 For Local y:Int = 0 To yPoints For Local x:Int = 0 To xPoints grid.vector[x,y].x = .2 grid.vector[x,y].y = Sin(x*10)+1 Next Next Case 2 Local b:Float, d:Int, angleOffset:Int Local c:Float = RndFloat()*.6+.2 angleOffset = Rnd(100)-30 For Local y:Int = 0 To yPoints For Local x:Int = 0 To xPoints grid.vector[x,y].x = -.4*Cos(angleOffset) d=0 If y > (yPoints*c) Then d=180'b = -b b = Sin(x*(10-x)+(d+angleOffset)) grid.vector[x,y].y = b Next Next Default EndSelect EndMethod Method explode() For Local y:Int = 0 To yPoints For Local x:Int = 0 To xPoints If Rnd()<.2 grid.vector[x,y].x:+(RndFloat()-.5)*15 grid.vector[x,y].y:+(RndFloat()-.5)*15 EndIf Next Next EndMethod Method kill() For Local y:Int = 0 To yPoints For Local x:Int = 0 To xPoints grid.vector[x,y].x=0 grid.vector[x,y].y=0 Next Next EndMethod Method drawGradient() glbegin Gl_Quads glcolor3f 0.9, 0.4, 0.1 glvertex3f 2, 2, 0 glvertex3f 80, 2, 0 glvertex3f 80, 72, 0 glvertex3f 2, 52, 0 glend EndMethod Method drawVectors() Local xPos:Int, yPos:Int For Local yarray:Int = 0 To yPoints-2 For Local xarray:Int = 0 To xPoints-2 xPos = xCenter + xArray * resolution yPos = yCenter + yArray * resolution SetColor 250,0,0 Drawl xPos,yPos, vector[xArray, yArray].x*20, vector[xArray, yArray].y*20,1,LINE Next Next EndMethod EndType Global grid:gridType = New gridType Type timerType Field t50Flag:Int, t50:Int Field t22000Flag:Int, t22000:Int Method update() t50Flag = 0 t22000Flag = 0 If MilliSecs()-t50 >50 t50Flag = 1; t50 = MilliSecs() If MilliSecs()-t22000>22000 t22000Flag = 1; t22000 = MilliSecs() EndMethod Method New() t50 = MilliSecs() t22000 = MilliSecs()-10000 EndMethod EndType Type colourSchemeType 'colour[which particle, which overall scheme] Field redCls:Float, greenCls:Float, blueCls:Float Field redClsTarget:Float, greenClsTarget:Float, blueClsTarget:Float Field r:Int[4,6], g:Int[4,6], b:Int[4,6] Field current:Int, totalSchemes:Int = 5 Method update() If timer.t22000Flag Then current:+1 If current> totalSchemes Then current = 0 changecolour() Select Rand(6) Case 1 grid.waterSmear(1) Case 2 grid.waterSmear(2) Case 3,4 grid.kill() For Local a:Int = 0 To particleNum -1 Step 2 'this makes half of the particles have reverse gravity particles[a].gravity=.08 Next Default grid.circles() If initialWaited = True And Rand(2) = 1 Then particleType.reset(4) EndSelect If initialWaited = False grid.circles() initialWaited = True EndIf If timer.t50Flag Then lazyParticleSpy.update() If redCls<redClsTarget redCls:+colourVolitility*.2 If redCls>redClsTarget redCls:-colourVolitility*.2 If GreenCls<GreenClsTarget GreenCls:+colourVolitility*.2 If GreenCls>GreenClsTarget GreenCls:-colourVolitility*.2 If BlueCls<BlueClsTarget BlueCls:+colourVolitility*.2 If BlueCls>BlueClsTarget BlueCls:-colourVolitility*.2 SetClsColor redCls, greenCls, blueCls EndIf EndMethod Method changeColour() redClsTarget=r[2, current]*.6 greenClsTarget=g[2, current]*.6 blueClsTarget=b[2, current]*.6 For Local a:Int = 0 To 3 particles[a].r = r[a, current] particles[a].g = g[a, current] particles[a].b = b[a, current] Next EndMethod Method debug() For Local y:Int = 0 To totalSchemes For Local x: Int = 0 To 3 SetColor r[x, y], g[x, y], b[x, y] DrawRect 40+x*60, 40+y*70, 57, 57 Next Next Flip WaitKey End EndMethod Method New() 'Colour Scheme 0 r[0,0]=000 g[0,0]=55 b[0,0]=000 r[1,0]=140 g[1,0]=196 b[1,0]=100 r[2,0]=158 g[2,0]=000 b[2,0]=001 r[3,0]=146 g[3,0]=155 b[3,0]=000 'Colour Scheme 1 r[0,1]=239 g[0,1]=186 b[0,1]=132 r[1,1]=165 g[1,1]=038 b[1,1]=039 r[2,1]=255 g[2,1]=95 b[2,1]=80 r[3,1]=155 g[3,1]=103 b[3,1]=043 'Colour Scheme 2 r[0,2]=010 g[0,2]=104 b[0,2]=000 r[1,2]=000 g[1,2]=150 b[1,2]=122 r[2,2]=040 g[2,2]=190 b[2,2]=000 r[3,2]=033 g[3,2]=033 b[3,2]=165 'Colour Scheme 3 r[0,3]=130 g[0,3]=030 b[0,3]=150 r[1,3]=066 g[1,3]=025 b[1,3]=165 r[2,3]=145 g[2,3]=060 b[2,3]=040 r[3,3]=000 g[3,3]=111 b[3,3]=155 'Colour Scheme 4 r[0,4]=037 g[0,4]=185 b[0,4]=126 r[1,4]=255 g[1,4]=186 b[1,4]=156 r[2,4]=255 g[2,4]=121 b[2,4]=066 r[3,4]=055 g[3,4]=095 b[3,4]=020 'Colour Scheme 5 r[0,5]=000 g[0,5]=005 b[0,5]=080 r[1,5]=132 g[1,5]=130 b[1,5]=198 r[2,5]=074 g[2,5]=024 b[2,5]=239 r[3,5]=074 g[3,5]=060 b[3,5]=000 EndMethod EndType Global colourScheme:colourSchemeType = New colourSchemeType colourScheme.current = Rand(colourScheme.totalSchemes) 'colourScheme.debug() Type particleType Field x:Float, y:Float Field x1:Float, y1:Float Field r:Int, g:Int, b:Int Field xGrid:Int, yGrid:Int Field gravity:Float Method do(ID:Int) If timer.t50Flag Then If ID > 3 Then For Local a:Int = 0 To 3 If within(x, y, particles[a].x, particles[a].y, 50,50) Then If r < particles[a].r Then r:+colourVolitility If r>255 Then r = 255 EndIf If g < particles[a].g Then g:+colourVolitility If g>255 Then g = 255 EndIf If b < particles[a].b Then b:+colourVolitility If b>255 Then b = 255 EndIf If r > particles[a].r Then r:-colourVolitility If r<0 Then r = 0 EndIf If g > particles[a].g Then g:-colourVolitility If g<0 Then g = 0 EndIf If b > particles[a].b Then b:-colourVolitility If b<0 Then b = 0 EndIf EndIf Next ElseIf initialWaited Then For Local a:Int = 0 To 3 If ID <> a Then If within (x, y, particles[a].x, particles[a].y, 60, 60) Then x1:+(x-particles[a].x)*.05 y1:+(y-particles[a].y)*.05 EndIf EndIf Next EndIf EndIf x1:+(RndFloat()-.5)*.1 y1:+(RndFloat()-.5)*.1 x:+x1 y:+y1 y1:+gravity x1:*.9 y1:*.9 If x> grid.width+4 x = -4 If x< -4 x = grid.width+4 If y> grid.height+4 y = -4 If y< -4 y = grid.height+4 xGrid = x/grid.resolution yGrid = y/grid.resolution x1:+(grid.vector[xGrid, yGrid].x+grid.vector[xGrid+1, yGrid].x)*.5 y1:+(grid.vector[xGrid, yGrid].y+grid.vector[xGrid, yGrid+1].y)*.5 If ID = 10 And debug Then SetColor 200, 200, 200 drawl(x-25,y-25, 50, 50, 1, CORNERS) drawl(x-25,y-30, lazyParticleSpy.movementPoints*.5, 5,1, FILL) SetAlpha .2 DrawText "Keys: 1-reposition, 2-kill movement, 3-rand movement, 4-smear movement, 5-radial paths, 6-next", 5, 5 SetAlpha 1 EndIf SetColor r,g,b DrawImage poof,x+grid.xCenter, y+grid.yCenter EndMethod Function reset(which:Int = 0) If Not which Then which = Rand(4) Select which Case 1 For Local a:Int = 0 To particles.length-1 particles[a].x = grid.width*.5 particles[a].y = grid.height*.8 Next Case 2 For Local a:Int = 0 To particles.length-1 Local aa:Int = Rnd(360) particles[a].x = grid.width*.5+Rnd(grid.width*.4)*Sin(aa) particles[a].y = grid.width*.5+Rnd(grid.height*.4)*Cos(aa) Next Case 3, 4 For Local a:Int = 0 To particles.length-1 particles[a].x = Rnd(grid.width) particles[a].y = Rnd(grid.height) Next EndSelect EndFunction Method New() x = grid.width*.5 y = grid.height*.9 colourVolitility = 30 r = 55 g = 55 b = 55 gravity=-.06 EndMethod EndType Global particles:particleType[particleNum+1] Global timer:timerType = New timerType Global whichParticle:Int For Local a:Int = 0 To particleNum whichParticle = a particles[a] = New particleType Next Type mouseType Field x:Int, y:Int Field x1:Int, y1:Int Method update() x1 = x-MouseX() y1 = y-MouseY() If Abs(x1)>5 Or Abs(y1)> 5 Then If Abs(x1)< 50 And Abs(y1)<50 Then End EndIf x = MouseX() y = MouseY() EndMethod Method New() x=MouseX() y=MouseY() x1=0 y1=0 EndMethod EndType Global mouse:mouseType = New mouseType mouse.update() HideMouse() Repeat timer.update() colourScheme.update() grid.drawGradient() If grid.show grid.drawVectors() grid.calmDown() For Local a:Int = 0 To particles.length-1 particles[a].do(a) Next mouse.update() If KeyHit(key_1) particleType.reset() If KeyHit(key_2) grid.kill() If KeyHit(key_3) grid.explode() If KeyHit(key_4) grid.waterSmear() If KeyHit(key_5) grid.circles() If KeyHit(key_6) timer.t22000 = 0 SetColor 100, 100, 100 SetAlpha .05 SetColor 255, 255, 255 DrawText "2009 'Dubious Drewski'", 620, 585 SetAlpha 1 Flip;Cls Until KeyDown(key_escape) Or AppTerminate() Or AppSuspended() End Function drawPoof:Timage(xsize:Int=32, ysize:Int=32) Local image:timage = CreateImage (xsize,ysize,,DYNAMICIMAGE) Local argb:Int,a:Int, r:Int, g:Int, b:Int Local xmid:Int = image.width*.5 Local yMid:Int = image.height*.5 Local temp:TPixmap = LockImage(image) For Local y:Int = 0 To image.height-1 For Local x:Int = 0 To image.width-1 Local scale:Float = 255.0/xMid argb=0 Local dist:Float = Sqr((x-xMid)^2+(y-yMid)^2) a=(Xmid-dist)*scale argb:|a a = a Shl 8 argb:|a a = a Shl 8 argb:|a a = a Shl 8 argb:|a If dist> xMid argb=0 WritePixel(temp,x,y,argb) Next Next UnlockImage(image) SetBlend lightblend MidHandleImage(image) ' DrawImage(image, 40, 40);Flip;WaitKey';End Return image EndFunction Function within:Int(x1:Float,y1:Float,x2:Float,y2:Float,xsize:Int,ysize:Int) If x1>x2-xSize And x1< x2+xSize Then If y1>y2-ySize And y1< y2+ySize Return True EndIf Return False EndFunction Const NORMAL:Int = 0 Const DOTTED:Int = 1 Function drawEllipse(x:Int,y:Int,xSize:Int,ySize:Int,StepSize:Int = 15, width:Int=1, style:Int = NORMAL) Local oldlinewidth:Int = GetLineWidth(), dot:Int = 1 SetLineWidth width Local a:Int = stepSize Repeat If dot DrawLine x+xSize*Sin(a), y+ySize*Cos(a),x+xSize*Sin(a-stepSize), y+ySize*Cos(a-stepSize) a:+stepSize If style dot = 1-dot Until a> 360 SetLineWidth oldlinewidth EndFunction Const FILL:Int = 3 Const LINE:Int = 2 Const CORNERS:Int = 1 Const BOX:Int = 0 Function drawl(x1:Int,y1:Int,x2:Int,y2:Int,width:Int=1,style:Int = BOX) Local oldlinewidth:Int = GetLineWidth() SetLineWidth width Select style Case 3 DrawRect x1,y1,x2,y2 Case 2 x2:+x1 y2:+y1 DrawLine x1,y1,x2,y2 Case 1 x2:+x1 y2:+y1 DrawLine (x1,y1,x1+(x2-x1)*.1,y1) DrawLine (x1,y1,x1,y1+(y2-y1)*.1) DrawLine (x1,y2-(y2-y1)*.1,x1,y2) DrawLine (x1,y2,x1+(x2-x1)*.1,y2) DrawLine (x2,y1,x2-(x2-x1)*.1,y1) DrawLine (x2,y1,x2,y1+(y2-y1)*.1) DrawLine (x2,y2-(y2-y1)*.1,x2,y2) DrawLine (x2,y2,x2-(x2-x1)*.1,y2) Default x2:+x1 y2:+y1 DrawLine (x1,y1,x2,y1) DrawLine (x1,y1,x1,y2) DrawLine (x1,y2,x2,y2) DrawLine (x2,y1,x2,y2) EndSelect SetLineWidth oldlinewidth End Function