Game Counter & Odometer & Digital clock - all OS - [Module]

Share your advanced PureBasic knowledge/code with the community.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Game Counter & Odometer & Digital clock - all OS - [Mod

Post by Saki »

Code updated, Mac OS now with gradient colored text and clipping

Hi Kwai
many thanks again.

It was a lot of work, but it was going to be perfect.
Whenever I thought it was finished, I found bugs again during intensive testing under the different OS.
Disaster LOL.

Hi davido
It is already ready.
Is not so easy to see through how this works, but it works. :wink:
Under MacOS you can now do what you normally can't.
The text now has gradient colors.
I also replaced the broken clipping of PB under MacOS.

Image

Image

Image

Best Regards Saki
地球上の平和
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Game Counter & Odometer & Digital clock - all OS - [Mod

Post by davido »

@Saki,
Just tried your update. It looks Great. Thank you. :D
I now see where the Wizard reference originates.
DE AA EB
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Game Counter & Odometer & Digital clock - all OS - [Mod

Post by Saki »

The codes have been greatly expanded and revised.

The last update I had accidentally cut off the demo part, now it's back.
It had all become a bit too much for me, then you quickly make mistakes, get demotivated or overlook something.

If you notice something else, you can also send PN, it will be fixed right away.

Try the new desktop clock, it is very well done.
Compile it and put it into the autostart folder.
Have a look at the first post for the clock, the second code.
Image

I wish you all a lot of fun with it.
地球上の平和
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Game Counter & Odometer & Digital clock - all OS - [Mod

Post by mk-soft »

@Saki

The gadget looks good, but using EventWindow and Delay(1) consumes a lot of processor power.
Under macOS about 82% and under Windows about 12%.

This can also be reduced with AddWindowTimer.

Here is an example of a solution with window timer

Code: Select all

;-TOP

; Canvas Animate Timer Example by mk-soft, v1.01, date 26.03.2021

EnableExplicit

DeclareModule CommonCanvas
  
  Global CanvasTimerWindow
  
EndDeclareModule

Module CommonCanvas
  
  Procedure InitModule()
    CanvasTimerWindow = OpenWindow(#PB_Any, 0, 0, 0, 0, "CanvasTimerWindow", #PB_Window_Invisible)
  EndProcedure : InitModule()
  
EndModule

; ----

DeclareModule AnimateGadget
  
  Declare BoxGadget(Gadget, x, y, Width, Height, FrontColor, BackColor, BorderColor = 0)
  
EndDeclareModule

Module AnimateGadget
  
  EnableExplicit

  UseModule CommonCanvas
  
  Structure udtBoxGadget
    Gadget.i
    ; Parameters
    FrontColor.i
    BackColor.i
    BorderColor.i
    ; Internal data
    Counter.i
  EndStructure
  
  Global NewMap mapBoxGadget.udtBoxGadget()
  
  ; ----
  
  Procedure DrawBoxGadget(*Data.udtBoxGadget)
    Protected x, y, dx, dy, dx2, dy2
    
    With *Data
      If StartDrawing(CanvasOutput(\Gadget))
        dx = GadgetWidth(\Gadget)
        dy = GadgetHeight(\Gadget)
        ; Background
        Box(0, 0, dx, dy , \BackColor)
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(0, 0, dx, dy , \BorderColor)
        ; Counter
        \Counter + 2
        If \Counter > 100
          \Counter = 2
        EndIf
        ; Calc
        dx2 = (dx - 4) * \Counter / 100
        dy2 = (dy - 4) * \Counter / 100
        x = (dx - dx2) / 2
        y = (dy - dy2) / 2
        ; Foreground
        DrawingMode(#PB_2DDrawing_Default)
        Box(x, y, dx2, dy2, \FrontColor)
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(x, y, dx2, dy2, \BorderColor)
        StopDrawing()
      EndIf
    EndWith
    
  EndProcedure
  
  ; ----
  
  Procedure BoxGadget_TimerEvent()
    Protected *Data.udtBoxGadget = EventTimer()
    With *Data
      If Not IsGadget(\Gadget) ; gadget not longer exists
        Debug "Destroy data from gadget " + \Gadget
        ; Remove timer
        RemoveWindowTimer(CanvasTimerWindow, *Data)
        ; Destroy gadget data
        If FindMapElement(mapBoxGadget(), Str(\Gadget))
          DeleteMapElement(mapBoxGadget())
        EndIf
      Else
        ; Redraw Gadget
        DrawBoxGadget(*Data)
      EndIf
    EndWith
  EndProcedure
  
  ; ----
  
  Procedure BoxGadget(Gadget, x, y, Width, Height, FrontColor, BackColor, BorderColor = 0)
    Protected id, *Data.udtBoxGadget
    
    id = CanvasGadget(Gadget, x, y, Width, Height)
    If Not id
      ProcedureReturn 0
    EndIf
    
    If Gadget = #PB_Any
      Gadget = id
    EndIf
    
    ; Exists old gadget data
    If FindMapElement(mapBoxGadget(), Str(Gadget))
      ; Remove timer
      RemoveWindowTimer(CanvasTimerWindow, @mapBoxGadget())
      ; Destroy old gadget data
      DeleteMapElement(mapBoxGadget())
    EndIf
    
    *Data = AddMapElement(mapBoxGadget(), Str(Gadget))
    With *Data
      \Gadget = Gadget
      \FrontColor = FrontColor
      \BackColor = BackColor
      \BorderColor = BorderColor
    EndWith
    ; First draw
    DrawBoxGadget(*Data)
    ; Bind timer event
    BindEvent(#PB_Event_Timer, @BoxGadget_TimerEvent(), CanvasTimerWindow, *Data)
    ; Init timer 50 hz
    AddWindowTimer(CanvasTimerWindow, *Data, 20)
    ProcedureReturn id
  EndProcedure
    
EndModule

; ********

;-Example

Enumeration Windows
  #Main
EndEnumeration

Enumeration Gadgets
  #Box1
  #Box2
EndEnumeration

Enumeration Status
  #MainStatusBar
EndEnumeration

Procedure Main()
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 400, 200, "Animate Canvas Gadget" , #MainStyle)
    
    AnimateGadget::BoxGadget(#Box1, 10, 10, 60, 60, #Red, #Yellow)
    AnimateGadget::BoxGadget(#Box2, 80, 10, 60, 60, #Blue, #White)
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #Box1
              If EventType() = #PB_EventType_LeftDoubleClick
                FreeGadget(#Box1)
              EndIf
              
            Case #Box2
              If EventType() = #PB_EventType_LeftDoubleClick
                FreeGadget(#Box2)
              EndIf
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Game Counter & Odometer & Digital clock - all OS - [Mod

Post by Saki »

Thank you mk-soft.

I'll look for your solution.

Under MacOS, the GradientColor function is emulated, which is very computationally intensive.

If the clock is running as a desktop clock, you can increase the delay to approx. 10 under MacOS, then the load decreases considerably.

Tomorrow I'll add a function to simply switch off the gradient colour, then the load will no longer be higher than under Windows.

Under Windows I have a very low load, this is on 4K and DPI aware.
Image
Running as a clock in an executable is therefore always uncritical in itself,
since most cores of a modern CPU are hardly or not used anyway.

Best Regards Saki
Last edited by Saki on Sat Mar 27, 2021 11:19 am, edited 2 times in total.
地球上の平和
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Game Counter & Odometer & Digital clock - all OS - [Mod

Post by Saki »

Codes updated

Now you can disable gradient colors with a function call, also inside the Desktop clock menu.

I had forgotten to save all changed settings of the desktop clock, that works now too.

For the Gradient Color emulation under MacOS you can set a quality factor at the top of the Odometer code,
which sets the edge smoothing.
This factor is set to 1.4, higher is better, lower is more worse but faster.

With a window timer it won't work, because it affects the odometer by its low priority,
mainly if the system clock doesn't synchronize the seconds.

I have to reconsider this though, if I can put it in for the frame delays on the clock.
But it clashes, when I hang in the WaitWindowEvent, I can't synchronize the endpoint
of the frame animation with the system clock anymore.
Switching between window timer and delay check before the end point of the animation is also not possible,
this is seen as jerking or frame skip, because then the synchronization is broken, difficult.

When the clock is large, or very large, the delay quickly fades into the background, especially on 4K and DPI aware.
The resource requirements always increase progressively with the size.

Interesting, on an 8K monitor, you probably can't animate anything without a GPU with the machines currently in use.

It's amazing how such a small thing can annoy you with programming pitfalls.

Well, that's probably the reason why I've never seen such a clock working.

But it is an eye catcher, you just have to have it once you see it. LOL
地球上の平和
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Game Counter & Odometer & Digital clock - all OS - [Mod

Post by Saki »

Codes updated and extended

The odometer main module is greatly expanded.
Interesting functions for working with the clock have been added.
All known and detected bugs have been fixed.

Everything is extensively tested on all OS.


The desktop clock module now uses a new feature of the main odometer module,
which automatically adjusts the speed of the clock animation,
no matter how big or small the clock is, or how fast or slow the used computer is.

This function adjusts the resource requirements of the desktop clock completely automatically.
This happens under consideration of the performance of the respective computer,
the clock size or even the complex GradientColor emulation under MacOS.

During the clock runs, everything adjusts automatically, Including the resource requirements.
This was quite difficult to implement, which is why it took almost two days to get everything running.
But it works perfect.

It's an interesting thing.
It's the first function I know of which can get the needed
resources on the fly and frees resources that are not needed.

You can see here in the gif how the delay is automatically adjusted.
I have not seen anything like this anywhere else.

When another application requests resources, the delay decreases again and levels itself again.

Image
地球上の平和
Post Reply