Screensavers and mouse position

BlitzMax Forums/BlitzMax Programming/Screensavers and mouse position

hi i am still mucking about with getting screensavers perfect..this is what i have

Framework brl.GLMax2D
Import brl.Basic
Import brl.System
Import brl.Retro
Import pub.Win32
Import brl.RamStream
Import brl.PNGLoader
Import BRL.Random
Import brl.timer
Import "-lshell32"
Import "-luser32"
Import "-lkernel32"


Extern "win32"
	Function FindWindow (x:Byte Ptr, y:Byte Ptr) = "FindWindowA@8"
	Function MoveWindow (hWnd,x,y,w,h,d) = "MoveWindow@24"
	Function ShowWindow (hWnd,style) = "ShowWindow@8"
	Function GetWindowLong (hwnd, nIndex) = "GetWindowLongA@8"
	Function SetWindowLong (hWnd,x,y) = "SetWindowLongW@12"
	Function SetParent (hWnd1,hWnd2) = "SetParent@8"
	Function IsWindowVisible (hWnd) = "IsWindowVisible@4"
	Function GetDesktopWindow () = "GetDesktopWindow@0"
	Function GetWindowRect (hWnd:Int,r:Byte Ptr) = "GetWindowRect@8"
	Function CreateSemaphore (a:Byte Ptr, b:Int, c:Int, d:String) = "CreateSemaphoreW@16"
	Function GetLastError () = "GetLastError@0"
EndExtern

'**************** Get Current Desktop Resolution *******************
Global r:Int[4] 
Global p:Byte Ptr = Varptr( r[0] ) 

' This is advisable because it is best not to switch screen
deskWnd = GetDesktopWindow()  		' settings when the screen saver starts.
GetWindowRect(deskWnd, p) 

Global DeskWidth :Float =r[2]
Global DeskHeight:Float =r[3] 
'**************** End Get Current Desktop Resolution ***************

Global Width: Float = 0
Global Height:Float = 0
Global startmousex:Int = 0
Global startmousey:Int = 0

Const ERROR_ALREADY_EXISTS:Int = 183
Const PREVIEW_ACTIVE:Int = 0
Const CONFIG_ACTIVE:Int = 1
Const SAVER_ACTIVE:Int = 2

Global PrevWnd:Int
If AppArgs.length = 3
	PrevWnd:Int = Int(AppArgs[2] )  	'Handle of the preview window
EndIf
Global pscale:Float = 1 				'scale value to apply depending on screen size
Global bmw:Int = 0 						'Handle of the BMax window
Global Status:Int = 0 					'Program status, identifies preview, regular, or config modes
Global timemark:Int = 0 				'Time marker to use for a makeshift timer

'Global test = 0	'config
Global test = 1 'normal'
'Global test=2'screensaver
SetGraphicsDriver GLMax2DDriver( )

config.loadconfig()
Global dot:timage

If test = 1
	If AppArgs.length > 1
		Select AppArgs[1]
			Case "/p"
				InitPreviewMode( )
			Case "/s"
				InitSaverMode() 
			Case "/c"
				InitConfigMode( )
			Default
				InitConfigMode( )
		End Select  
	Else
		InitConfigMode() 
	EndIf
Else
	If test = 0 InitConfigMode() Else InitSaverMode() 
EndIf


 
For Local i = 0 To config.circle_co
	Tstreak.Create() 
Next
Tstreak.Create(config.circle_user_mode) 

HideMouse

While Not KeyHit( KEY_ESCAPE )

	Cls
	
	'	UpdateAppTime(120) 

		Tstreak.update() 
		Tstreak.draw() 
		
	Flip
	GCCollect
	Delay 1
'******* This block is boilerplate ********
If test <> 0' 1
	Select Status
		Case PREVIEW_ACTIVE
			CheckVisible( )
		Case SAVER_ACTIVE
			CheckMovement( )
	End Select
EndIf
'************* Do Not Remove **************

Wend

End

Type config

	Global circle_user_mass = 25, circle_user_mode = 1
	Global circle_co = 100, circle_size = 30
	Global circle_max_mass = 60, circle_min_mass = 20
	Global circle_max_speed = 12, circle_min_speed = 0
	Global circle_mode = 0, menu = 0
	
	Function loadconfig()
		Local levfile:TStream=ReadFile("circle.cfg")
		If levfile=Null
			saveconfig()
		Else		
			levfile:TStream=ReadFile:TStream("circle.cfg")
			circle_co=ReadInt(levfile)
			circle_size=ReadInt(levfile)
			circle_max_mass=ReadInt(levfile)
			circle_min_mass=ReadInt(levfile)
			circle_max_speed=ReadInt(levfile)			
			circle_min_speed=ReadInt(levfile)
			circle_user_mode=ReadInt(levfile)
			circle_mode=ReadInt(levfile)
			CloseFile(levfile)		
		EndIf
	End Function
	
	Function saveconfig()
		Local levfile:TStream=WriteFile:TStream("circle.cfg")
		WriteInt(levfile,circle_co)
		WriteInt(levfile,circle_size)
		WriteInt(levfile,circle_max_mass)
		WriteInt(levfile,circle_min_mass)
		WriteInt(levfile,circle_max_speed)				
		WriteInt(levfile,circle_min_speed)
		WriteInt(levfile,circle_user_mode)
		WriteInt(levfile,circle_mode)
		CloseFile(levfile)		
	EndFunction
	
End Type


Type Tstreak

Global streaks:TList = New TList

	Field x:Float, y:Float, sp:Float, ty:Int

	Field dx:Float, dy:Float 
	Field lmx:Float, lmy:Float
	Field radius:Float 
	Field mass:Float 
	

Function Create(ty = 0) 
	Local s:Tstreak = New Tstreak
	s.x = Rand(0 + config.circle_size / 2, DeskWidth - config.circle_size / 2) 
	s.y = Rand(0 + config.circle_size / 2, DeskHeight - config.circle_size / 2) 
	s.dx = Rand(config.circle_min_speed, config.circle_max_speed) - config.circle_max_speed / 2
	s.dx = Rand(config.circle_min_speed, config.circle_max_speed) - config.circle_max_speed/2
	s.radius = config.circle_size / 2
	s.mass = Rand(config.circle_min_mass, config.circle_max_mass) 
	s.ty = ty
	If ty = 1 Then s.mass = config.circle_user_mass
	streaks.addlast s
End Function

Function update() 
	For Local c:Tstreak = EachIn streaks
	If c.ty = 1
		c.dx = (c.x - MouseX() )'*  AppSpeed:Float()
		c.dy = (c.y - MouseY() )'*  AppSpeed:Float()
		If c.dx > config.circle_max_speed Then c.dx = config.circle_max_speed
		If c.dy > config.circle_max_speed Then c.dy = config.circle_max_speed
		c.x = MouseX()
		c.y = MouseY()
	Else
		c.x = c.x + c.dx '*  AppSpeed:Float() 
		c.y = c.y + c.dy' *  AppSpeed:Float() 
		If c.dx > config.circle_max_speed Then c.dx = c.dx * 0.95
		If c.dy > config.circle_max_speed Then c.dy = c.dy * 0.95
		For Local c2:Tstreak = EachIn streaks
			
			collisionDistance:Float = c.radius + c2.radius
			actualDistance:Float = Sqr((c2.x - c.x) ^ 2 + (c2.y - c.y) ^ 2) 

			If actualDistance<collisionDistance Then
				
				collNormalAngle:Float = ATan2(c2.y - c.y, c2.x - c.x) 

				moveDist1:Float = (collisionDistance - actualDistance) * (c2.mass / Float((c.mass + c2.mass))) 
				moveDist2:Float = (collisionDistance - actualDistance) * (c.mass / Float((c.mass + c2.mass))) 
				c.x = c.x + moveDist1 * Cos(collNormalAngle + 180) 
				c.y = c.y + moveDist1 * Sin(collNormalAngle + 180) 
				c2.x = c2.x + moveDist2 * Cos(collNormalAngle) 
				c2.y = c2.y + moveDist2 * Sin(collNormalAngle) 
				
				nX:Float = Cos(collNormalAngle) 
				nY#=Sin(collNormalAngle)

				a1:Float = c.dx * nX + c.dy * nY
				a2:Float = c2.dx * nX + c2.dy * nY
				
				optimisedP:Float = (2.0 * (a1 - a2)) / (c.mass + c2.mass) 

				c.dx = c.dx - (optimisedP * c2.mass * nX) 
				c.dy = c.dy - (optimisedP * c2.mass * nY) 
				
				c2.dx = c2.dx + (optimisedP * c.mass * nX) 
				c2.dy = c2.dy + (optimisedP * c.mass * nY) 
				
			End If
		
		Next
		
		If c.x < c.radius Then
			c.x = c.radius
			c.dx = c.dx * -1
		End If
		If c.x > DeskWidth - c.radius Then
			c.x = DeskWidth - c.radius
			c.dx = c.dx * -1
		End If
		If c.y < c.radius Then
			c.y = c.radius
			c.dy = c.dy * -1
		End If
		If c.y > DeskHeight - c.radius Then
			c.y = DeskHeight - c.radius
			c.dy = c.dy * -1
		End If
	EndIf
	Next

End Function

Function draw() 

	For Local c:Tstreak = EachIn streaks
		If c.ty = 0 Then SetColor 255, 20, 20 Else SetColor 255, 255, 20
		DrawImage dot,c.x*pscale,c.y*pscale,0
	Next
	SetColor 255, 255, 255
	
End Function

End Type


Function InitSaverMode() 

	If SetProcessLock( "SaverModeLock" ) <> 0 Then End
	Status = SAVER_ACTIVE
	Width = DeskWidth
	Height = DeskHeight
	Graphics Width, Height, 32'-1, -1
	dot = CreateImage(config.circle_size, config.circle_size) 
	SetColor 255, 250, 250
	DrawOval 0, 0, config.circle_size, config.circle_size
	GrabImage(dot, 0, 0)
	
	SetWindowPos(FindWindow(Null, "BlitzMax Application"), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE) 
	pscale = 1
	SetScale pscale, pscale
	Return
	
EndFunction

Function InitPreviewMode() 

	If SetProcessLock("PreviewModeLock") <> 0 Then End
	Status = PREVIEW_ACTIVE
	Width = 152
	Height = 112
	Graphics Width, Height, 0, - 1
	dot = CreateImage(config.circle_size, config.circle_size) 
	SetColor 255, 250, 250
	DrawOval 0, 0, config.circle_size, config.circle_size
	GrabImage(dot, 0, 0)	
	
	bmw = FindWindow( Null, "BlitzMax Application" )
	Local bmx_Style = GetWindowLong( bmw, -16 )
	bmx_Style = bmx_Style And $40000000 Or $800000 And $10000000
	SetWindowLong bmw, -16, bmx_Style;
	SetParent( bmw,PrevWnd )
	MoveWindow ( bmw, 0, 0, 152, 112, True )	
	timemark = MilliSecs() 
	FlushMouse
	FlushKeys
	pscale = 152/DeskWidth
	SetScale pscale,pscale	
	Return
	
EndFunction
'
Function InitConfigMode() 

	Status = CONFIG_ACTIVE
	Width = 640
	Height = 480
	AppTitle = "Interactive Screensaver option"
	Graphics Width,Height, 0
	bmw = FindWindow( Null, "Configuration Screen" )
	MoveWindow ( bmw, ( DeskWidth/2-Width/2 ),( DeskHeight/2-Height/2 ), 320, 200, True )
	SetClsColor 46, 16, 112
	SetColor 255, 255, 255
'
'
	
	
	'end setup button
	Repeat
		Cls
			DrawText "do stuff here",10,20			
		Flip
	Until KeyHit(KEY_ESCAPE) Or config.menu>0

EndFunction
'
Function SetProcessLock:Int(LockStr:String) 
	Global MySem = CreateSemaphore( Null, 0, 1, LockStr )
	If MySem <> 0 And GetLastError( ) = ERROR_ALREADY_EXISTS
		Return 1
	Else
		Return 0
	EndIf
EndFunction

Function CheckVisible( )
	If MilliSecs() - timemark > 2000
		If Not IsWindowVisible(PrevWnd) 
			End
		EndIf
	EndIf
EndFunction

Function CheckMovement( )
	If GetChar() <> 0 Then End
	If KeyHit(KEY_SPACE) Then End
	If KeyHit(KEY_ENTER) Then End
EndFunction


the trouble i am having is with the mousex() and mousey() position of c.ty=1

the use cursor

for some reason it doe not orientate to true like the rest of the balls what silly mistake am i making....anybody got any ideas..


I got a feeling its got something to with the pscale factor and or the x,y start position based on the windows desktop preferences screen......all the rest of the object move ok, right size and scale, the mouse one c.ty=1 is right scale just wrong x,y screen position...any ideas..

It looks to me that the mouse position is fine, you just move the yellow ball to max screen coords, so it goes out of screen.
Just make the mousearea a ballsize smaller than the actual screen.