Creating MAX Screensaver
BlitzMax Forums/BlitzMax Programming/Creating MAX Screensaver
| ||
I am trying to build a screensaver in Max. I mean a real screensaver with a config-dialog and a preview-window also. so only changing the .exe to .scr will not be sufficient ;) i found this code which seems to have all features i need: http://www.blitzmax.com/Community/posts.php?topic=48729#542024 But it is rather old as it still uses FlushMem. I finally got it to compile under Max 1.20 when i: 1. changed FlushMem to GCCollect 2. put some fake arguments in the commandline (because AppArgs[2] gives me an error otherwise) Now it shows the config dialog and the preview allright. But it does not start the screensaver. also clicking "Preview" in the windows-screensaver-dialog runs the saver silently, gathering only lots of memory in the taskmanager. I also tried the example beneath the topic and this one works ok. I do not have the code but i guess it was compiled with an old MAX version also. Can someone help me converting this code to work with the latest version MAX (v. 1.20) ? |
| ||
I wish there were code to make screensavers easily on all platforms. |
| ||
Just sorted it out :D Can a few of you check out if this works on your systems too? it was only a bug with the AppArgs[] array: '******************** Open Source Screensaver Program ************************ ' ' Version 1.1 June 27, 2006 ' ' Known issues: None at this time ' ' Contributors: netmaestro, eikon, chris c, Uncle Ho ' ' ' Use: Compile with "GUI App" CHECKED ' Rename .exe to .scr ' move .scr to c:\windows\system32 (or...) ' '***************************************************************************** Framework BRL.GLMax2D Import BRL.Basic Import BRL.System Import BRL.Retro 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 SetGraphicsDriver GLMax2DDriver( ) If AppArgs.length > 1 Select AppArgs[1] Case "/p" InitPreviewMode( ) Case "/s" InitSaverMode( ) Case "/c" InitConfigMode( ) Default InitConfigMode( ) End Select Else InitConfigMode( ) EndIf While not KeyHit( KEY_ESCAPE ) '**************** TODO: Write your own presentation code *************** ' ' Multiply any scaling by pscale (=1 in Saver mode, .15-.25 in Preview) ' You will scale your speeds too (nothing moving in this one) ' '*********************************************************************** Cls SetColor 255,255,255 DrawOval 0,0,200,200 SetColor 255,0,0 DrawOval Width-(200*pscale),0,200,200 SetColor 0,255,0 DrawOval 0,Height-(200*pscale),200,200 SetColor 0,0,255 DrawOval Width-(200*pscale),Height-(200*pscale),200,200 Flip GCCollect '******* This block is boilerplate ******** Select Status Case PREVIEW_ACTIVE CheckVisible( ) Case SAVER_ACTIVE CheckMovement( ) End Select '************* Do Not Remove ************** Wend End Function InitSaverMode() If SetProcessLock( "SaverModeLock" ) <> 0 Then End Status = SAVER_ACTIVE Width = DeskWidth Height = DeskHeight Graphics Width, Height, -1, -1 pscale = 1 startmousex = MouseX( ) startmousey = MouseY( ) Return EndFunction Function InitPreviewMode( ) If SetProcessLock( "PreviewModeLock" ) <> 0 Then End Status = PREVIEW_ACTIVE Width = 152 Height = 112 Graphics Width, Height, 0, -1 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 ) pscale = 152/DeskWidth SetScale pscale, pscale timemark = MilliSecs() Return EndFunction Function InitConfigMode( ) Status = CONFIG_ACTIVE Width = 320 Height = 200 AppTitle = "Configuration Screen" Graphics Width,Height, 0 bmw = FindWindow( Null, "Configuration Screen" ) MoveWindow ( bmw, ( DeskWidth/2-Width/2 ),( DeskHeight/2-Height/2 ), 320, 200, True ) SetClsColor 192, 192, 192 SetColor 0, 0, 0 Cls DrawText "TODO: Write config code", 50, 80 DrawText "Press <ANY KEY> to exit", 55, 130 Flip WaitKey End 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 'Delay visibility check til window is drawn If not IsWindowVisible( PrevWnd ) End EndIf EndIf EndFunction Function CheckMovement( ) If MouseX( ) <> startmousex or MouseY( ) <> startmousey Then End If GetChar( ) <> 0 Then End 'Probably want to put some more keyhits in here; I'm too lazy EndFunction |
| ||
If you run this for a long time does it crash? ie If you leave the computer in screen saver all night rather than closedown, will it still be running tomorrow And two, does it hang when the computer turns on/off the monitor. And Three, does it still appear on the task bar as a running application, after it has stopped running? |
| ||
As it is the same Framework I have used by my screensaver in BMax it should work :) . For more details: DOWNLOAD SOME SCREENIES @H&K: For me my screenie was running 5 days without interruption, with monitor turning on and off. And it is invisible in the taskbar, but sometimes the preview mode will hang in the Taskmanager, to handle this I have simply added a delay to the mainloop of the preview code, so it will work. |
| ||
Now we just need Mac and Linux version ;-D |
| ||
Digging up this old thread because I have a problem using the code. I can't seem to load an image in the screensaver. I know the files exist but the images all return null. This all worked before I converted to a screen saver. Anyone know what the problem could be? |
| ||
It could be the Framework command, making it not import any Image loaders. Try removing it, or adding the image loader imports manually. |
| ||
Well done Grable. You cracked it. This has held me up for ages. I don't understand why it didn't moan at compile time though. |
| ||
Well nearly there now. I can see the screensaver fine in the small preview panel, but when I hit preview or set the screensaver to run, I don't see anything and my CPU usage shoots up. |
| ||
Can someone try the posted code with the latest Blitz? It shows previews here but nothing else. |
| ||
Heres a copy working in 1.26, just some minor fixes. |
| ||
is there a reason, or is it just on my machine that the preview whilst in the screen save tab on desktop preferences....it is very flickery is it actually running too fast and needs to be slown down, is it skipping and not waiting for the vertical blank......I modified it because between the two versions on this page neither worked coreectly but this hacked version seems to.....any ideas...'******************** Open Source Screensaver Program ************************ ' ' Version 1.1 June 27, 2006 ' ' Known issues: None at this time ' ' Contributors: netmaestro, eikon, chris c, Uncle Ho ' ' ' Use: Compile with "GUI App" CHECKED ' Rename .exe to .scr ' move .scr to c:\windows\system32 (or...) ' '***************************************************************************** Framework BRL.GLMax2D Import BRL.Basic Import BRL.System Import brl.Retro Import pub.Win32 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 SetGraphicsDriver GLMax2DDriver( ) If AppArgs.length > 1 Select AppArgs[1] Case "/p" InitPreviewMode( ) Case "/s" InitSaverMode( ) Case "/c" InitConfigMode( ) Default InitConfigMode( ) End Select Else InitConfigMode( ) EndIf While not KeyHit( KEY_ESCAPE ) '**************** TODO: Write your own presentation code *************** ' ' Multiply any scaling by pscale (=1 in Saver mode, .15-.25 in Preview) ' You will scale your speeds too (nothing moving in this one) ' '*********************************************************************** Cls SetColor 255,255,255 DrawOval Rnd(1024), Rand(768), 200, 200 SetColor 255, 0, 0 DrawOval Rnd(1024), Rand(768), 200, 200 SetColor 0,255,0 DrawOval Rnd(1024), Rand(768), 200, 200 SetColor 0,0,255 DrawOval Rnd(1024), Rand(768), 200, 200 Flip GCCollect '******* This block is boilerplate ******** Select Status Case PREVIEW_ACTIVE CheckVisible( ) Case SAVER_ACTIVE CheckMovement( ) End Select '************* Do Not Remove ************** Wend End Function InitSaverMode() If SetProcessLock( "SaverModeLock" ) <> 0 Then End Status = SAVER_ACTIVE Width = DeskWidth Height = DeskHeight Graphics Width, Height, 32'-1, -1 SetWindowPos(FindWindow(Null, "BlitzMax Application"), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE) pscale = 1 startmousex = MouseX( ) startmousey = MouseY() FlushMouse FlushKeys Return EndFunction Function InitPreviewMode( ) If SetProcessLock("PreviewModeLock") <> 0 Then End Status = PREVIEW_ACTIVE Width = 152 Height = 112 Graphics Width, Height, 0, -1 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 ) pscale = 152/DeskWidth SetScale pscale, pscale timemark = MilliSecs() Return EndFunction Function InitConfigMode( ) Status = CONFIG_ACTIVE Width = 320 Height = 200 AppTitle = "Configuration Screen" Graphics Width,Height, 0 bmw = FindWindow( Null, "Configuration Screen" ) MoveWindow ( bmw, ( DeskWidth/2-Width/2 ),( DeskHeight/2-Height/2 ), 320, 200, True ) SetClsColor 192, 192, 192 SetColor 0, 0, 0 Cls DrawText "TODO: Write config code", 50, 80 DrawText "Press <ANY KEY> to exit", 55, 130 Flip WaitKey End 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 'Delay visibility check til window is drawn If not IsWindowVisible( PrevWnd ) End EndIf EndIf EndFunction Function CheckMovement( ) If MouseX( ) <> startmousex or MouseY( ) <> startmousey Then End If GetChar( ) <> 0 Then End 'Probably want to put some more keyhits in here; I'm too lazy EndFunction oh and how do you do them scrolling boxes in this forum..... |
| ||
oh and how do you do them scrolling boxes in this forum..... use "codebox" instead of "code" ;) |
| ||
Anyone create a screensaver using this code? I'd like to download it and have a peek on my various test boxes. Thanks! |
| ||
http://www.filecrunch.com/fileDownload.php?sub=bca2128a6c04db37f0e2c272d9547850&fileId=138279 try this |
| ||
Dream: "This file is a private File. So you don't have rights to download this file." Available any place else? |
| ||
http://www.filecrunch.com/fileDownload.php?sub=bca2128a6c04db37f0e2c272d9547850&fileId=138279 sorry only just started using that site didnt realise they were private automatically try that again |
| ||
Thanks Dream, I've downloaded the compiled app and I've been playing with the source. I can verify that vsync is not working in preview mode and possibly the entire internal timing seems to get thrown off inside a cls/flip loop while in preview mode. Other than that, it does seem to work, this could be interesting. The most obvious solution is simply not run anything animated in preview mode, just show a static image or something. Alot of screensavers do that anyway. In any event, this deserves alot more of my attention and it may find it's way into my development shell. Thanks! ;) |
| ||
me too found the same thing in the end i added a timing delay, but the trick is working out how fast that little window is running at seems at lest triple if not 4 times as fast, now depending on system specs its going to fly on some bigger machines.....might have to build an fps counter for it in both preview and real and compare them. at the moment i have added a timing routine from the archives http://www.blitzbasic.com/codearcs/codearcs.php?code=2152 thanks to Leadwerks, but it isnt very effective in the preview window seems to be based on the whole windows system rather than that little window so may need to alter it... this is the main code now this is the timing code from leadwerks i called it "Timimingmodule.bmx" and is an include this is the link to the working version i have http://www.filecrunch.com/fileDownload.php?sub=2918da1da91be977f0e05a006fff0250&fileId=138534 i just realised i forgoto to take out some of the modules for png and jpeg loading so the file is bloated...doh...works though.. |
| ||
I'm just going to go with a static image in preview mode and just use the windows api call sleep() to give resources back to the system during that loop. Seriously, I don't think it's too much of a show stopper to not have a real time preview. Thanks for the info, comments on this. I've been looking for some stable windows screensaver code for a while, still need to run some tests on Vista to how this is going to work. ;) |