11package main
22
3- import ("fmt" ; "log " ; "unsafe " ; "time " ; w "golang.org/x/sys/windows" )
3+ import ("bufio" ; " fmt" ; "os " ; "os/exec " ; "strings " ; "syscall" ; "golang.org/x/sys/windows" )
44
5- type ADLTemperature struct {
6- Size int32
7- Temperature int32
5+ var eventPtr = utf16 ("Global\\ HotAMD" )
6+
7+ func main () {
8+ initialize ()
9+ if len (os .Args ) > 1 && os .Args [1 ] == "--daemon" {
10+ runDaemon ()
11+ } else {
12+ runCLI ()
13+ }
14+ close ()
815}
916
10- type ADLFanSpeedValue struct {
11- Size int32
12- SpeedType int32
13- FanSpeed int32
14- Flags int32
17+ func runDaemon () {
18+ h , e := windows .CreateEvent (nil , 1 , 0 , eventPtr )
19+ if e != nil { return }
20+ defer windows .CloseHandle (h )
21+ go start ()
22+ windows .WaitForSingleObject (h , windows .INFINITE )
1523}
1624
17- var (
18- dll = w .NewLazySystemDLL ("atiadlxx.dll" )
19- ADL_Main_Control_Create = dll .NewProc ("ADL_Main_Control_Create" ).Call
20- ADL_Main_Control_Destroy = dll .NewProc ("ADL_Main_Control_Destroy" ).Call
21- ADL_Adapter_NumberOfAdapters_Get = dll .NewProc ("ADL_Adapter_NumberOfAdapters_Get" ).Call
22- ADL_Overdrive5_Temperature_Get = dll .NewProc ("ADL_Overdrive5_Temperature_Get" ).Call
23- ADL_Overdrive5_FanSpeed_Get = dll .NewProc ("ADL_Overdrive5_FanSpeed_Get" ).Call
24- )
25-
26- func utf16 (s string ) * uint16 {
27- ptr , err := w .UTF16PtrFromString (s )
28- if err != nil { panic (err ) }; return ptr
25+ func runCLI () {
26+ reader := bufio .NewReader (os .Stdin )
27+
28+ for {
29+ cmd := exec .Command ("cmd" , "/c" , "cls" )
30+ cmd .Stdout = os .Stdout
31+ cmd .Run ()
32+
33+ fmt .Println ("♨️ HotAMD" )
34+
35+ isRunning := isRunning ()
36+
37+
38+ if isRunning {
39+ getAdapters ()
40+ temp , fan := readGPU (0 )
41+ fmt .Printf ("\n Temperature: %d°C\n " , temp )
42+ fmt .Printf ("Fan: %d RPM" , fan )
43+ }
44+ fmt .Print ("\n Daemon: " )
45+ if isRunning { fmt .Println ("running" ) } else { fmt .Println ("not running" ) }
46+
47+ fmt .Print ("\n 1) " )
48+ if isRunning { fmt .Print ("Stop " ) } else { fmt .Print ("Start " ) }
49+ fmt .Println ("daemon" )
50+ fmt .Println ("2) Exit" )
51+ fmt .Print ("\n > " )
52+
53+ input , _ := reader .ReadString ('\n' )
54+ input = strings .TrimSpace (input )
55+
56+ switch input {
57+ case "1" : if isRunning { stopDaemon () } else { startDaemon () }
58+ case "2" : return
59+ }
60+ }
2961}
3062
31- func alert (msg string ) {
32- w .MessageBox (0 , utf16 (msg ), utf16 ("Hotamd" ), w .MB_OK | w .MB_ICONWARNING )
63+ func isRunning () bool {
64+ handle , err := windows .OpenEvent (windows .SYNCHRONIZE , false , eventPtr )
65+ if err != nil { return false }
66+ windows .CloseHandle (handle )
67+ return true
3368}
3469
35- func main () {
36- adlMalloc := w .NewCallback (func (size int32 ) uintptr {
37- ptr , _ := w .LocalAlloc (0 , uint32 (size ))
38- return uintptr (ptr )
39- })
40- ADL_Main_Control_Create (adlMalloc , 1 )
41- defer ADL_Main_Control_Destroy ()
42-
43- var adapters int32
44- ADL_Adapter_NumberOfAdapters_Get (uintptr (unsafe .Pointer (& adapters )))
45- if adapters == 0 { log .Fatal ("GPU adapters not found" ) }
46- fmt .Println ("Adapters found:" , adapters )
47-
48- temp := ADLTemperature {Size : int32 (unsafe .Sizeof (ADLTemperature {}))}
49- fan := ADLFanSpeedValue {Size : int32 (unsafe .Sizeof (ADLFanSpeedValue {}))}
50-
51- for {
52- ADL_Overdrive5_Temperature_Get (0 , 0 , uintptr (unsafe .Pointer (& temp )))
53- temp := temp .Temperature / 1000
54- fmt .Printf ("GPU Temperature: %d °C\n " , temp )
55-
56- ADL_Overdrive5_FanSpeed_Get (0 , 0 , uintptr (unsafe .Pointer (& fan )))
57- rpm := fan .FanSpeed
58- fmt .Printf ("GPU Fan: %d RPM\n " , rpm )
59-
60- if temp > 40 && rpm == 0 {
61- alert ("GPU temperature > 40°C and fan is not spinning" )
62- } else if temp > 60 {
63- alert ("GPU temperature > 60°C" )
64- }
70+ func startDaemon () {
71+ if isRunning () { return }
72+ exe , _ := os .Executable ()
73+ cmd := exec .Command (exe , "--daemon" )
74+ cmd .SysProcAttr = & syscall.SysProcAttr { CreationFlags : 0x00000008 }
75+ cmd .Start ()
76+ }
6577
66- time .Sleep (10 * time .Second )
67- }
78+ func stopDaemon () {
79+ event , err := windows .OpenEvent (windows .EVENT_MODIFY_STATE , false , eventPtr )
80+ if err != nil { return }
81+ defer windows .CloseHandle (event )
82+ windows .SetEvent (event )
83+ fmt .Println ("Stopping daemon..." )
6884}
0 commit comments