Claximillions Posted April 7, 2012 Share Posted April 7, 2012 I'm trying to create this as a sort of trainer for StarCraft II. What I'm trying to do is #1 Calculate the team between every key press of mine. #2 Create a notification (Visual and Audio) to alert the user when the time between key presses is above x time. How would I do this? I glanced over the wiki and I doubt anyone has posted this previously. (APM = actions per minute) Quote Link to comment Share on other sites More sharing options...
shadowrecon Posted April 9, 2012 Share Posted April 9, 2012 (edited) Here is a head start on the code, i got bored and started messing around with your problem. You need to enable API calls under options in scar to allow for the counters to get the time. This just tell you the time between keys pressed no certain key just any key on the keyboard.. narrowing it down to a certain set of keys could get better results on speed an performance. [scar] Var AverageTime: Double; Time: Int64; Active: Boolean; Thread1: TTimer; Form1: TForm; function QueryPerformanceFrequency(out Frequency: Int64): LongBool; external 'QueryPerformanceFrequency@kernel32.dll stdcall'; function QueryPerformanceCounter(out Counter: Int64): LongBool; external 'QueryPerformanceCounter@kernel32.dll stdcall'; procedure MarkTime(var Time: Int64); var Freq: Int64; begin if QueryPerformanceFrequency(Freq) then QueryPerformanceCounter(Time) else Time := GetTickCount; end; function TimeFromMark(Mark: Int64): Double; var Freq, Now: Int64; begin if QueryPerformanceFrequency(Freq) then begin QueryPerformanceCounter(Now); Result := ((Now - Mark) / Freq) * 1000; end else Result := (GetTickCount - Mark); end; Procedure CheckKey(Sender: TObject); Var I: Integer; Key: Byte; Begin Key := 32; For I := 32 to 127 do Begin If IsKeyDown(Key) then Begin If Not (Active) then Begin Active := True; MarkTime(Time); Writeln('Key Pressed!'); end else Begin Active := False; AverageTime := TimeFromMark(Time); Writeln('Key Pressed Again!'); Writeln('Average Time Between Keys: '+FloatToStr(AverageTime)); end; Break; end; Inc(Key); end; end; Procedure SetupThreads; Begin Form1 := CreateForm; Thread1 := TTimer.Create(Form1); Thread1.Enabled := True; Thread1.OnTimer := @CheckKey; Thread1.Interval := 100; end; procedure SafeStart; var v: TVariantArray; begin setarraylength(v, 0); ThreadSafeCall('SetupThreads', v); end; Procedure FreeThreads; Begin Thread1.Free; FreeForm(Form1); end; procedure SafeStop; var v: TVariantArray; begin setarraylength(v, 0); ThreadSafeCall('FreeThreads', v); end; Procedure ScriptTerminate; Begin SafeStop; end; Begin SafeStart; Wait(100000); end. [/scar] EDIT: BTW this doesnt give the average time, it gives real time =p in MS (1000 ms make 1 second) ---------- Post added at 05:24 AM ---------- Previous post was at 04:58 AM ---------- Here is a simplified method that does the same thing i posted before. It has a resolution of about 115 ms between key strokes could be improved a good bit more but it lays out the ground work and this method actually gives the average time in MS between the key being pressed and another key being pressed. [scar] program TimingKeyStrokes; Var Mark: LongInt; AverageT: TIntArray; Active: Boolean; Procedure CheckKeys; Var Key: Byte; Begin Key := 38; Repeat If IsKeyDown(KEY)then If Not Active then Begin Active := True; Mark := GetTickCount; Break; end else Begin Active := False; SetLength(AverageT, Length(AverageT) + 1) AverageT[High(AverageT)] := (GetTickCount - Mark); Break; end; Inc(Key); until Key = 129; end; begin Repeat CheckKeys; Writeln('Average Time: '+FloatToStr(TIAMean(AverageT))); Wait(100); until False; end. [/scar] Edited April 9, 2012 by shadowrecon Quote Link to comment Share on other sites More sharing options...
Claximillions Posted April 11, 2012 Author Share Posted April 11, 2012 (edited) Sweet thanks that helps a lot!! Sorry for the late response, the forums had slipped my mind. Now that you were awesome enough to help me with this, do you know of any method that I could use to alert me? I'm not sure of anything I could use to like play a sound or make a visual cue.. EDIT: I've figured out how to alert myself. I found the 'PlaySound' function on the wiki >.< BUT NOW!!! how would I be able to adjust your second script you gave me to only average out.. say... the past 20 or so key presses? Not only for accuracy purposes but I'm guessing it would slow down after several minutes of constant key presses. Edited April 11, 2012 by Claximillions Quote Link to comment Share on other sites More sharing options...