root/thinkpad-saber/trunk/thinkpad-saber.pl

Revision 1911 (checked in by miyagawa, 14 years ago)

update Exit_Click to play off sound.

Line 
1 # ThinkPad Saber
2 # Copyright 2006 Tatsuhiko Miyagawa miyagawa at gmail.com
3 # License: Same as Perl (GPL or Artistic)
4
5 use strict;
6 use Cwd;
7 use File::Spec;
8 use Win32API::File qw(:ALL);
9 use Win32::GUI ();
10 use Win32::Sound;
11 use Time::HiRes qw(gettimeofday sleep);
12 use List::Util qw(max min);
13 use Getopt::Long;
14
15 our $VERSION = "0.23";
16
17 GetOptions('--debug', \my $debug, '--threshold=s' => \my $threshold, "--help" => \my $help);
18 Getopt::Long::Configure("bundling"); # allows -d -t
19
20 if ($help) {
21     print <<USAGE;
22 Usage: thinkpad-saber --debug --threshold=THRESHOLD
23
24 Options:
25   --debug     print out debug message
26   --threshold set threshold to play sound. (Defaults to 3.0)
27               Increasing this value means you have to shake your TP faster.
28 USAGE
29     exit;
30 }
31
32 my $cwd = cwd;
33 $threshold ||= 3.0;
34
35 # dummy main window
36 my $main = Win32::GUI::Window->new(
37     -name => 'Main',
38     -text => 'ThinkPad Saber',
39     -width => 200,
40     -height => 200,
41 );
42
43 my $icon_file = $INC{"PAR.pm"}
44     ? do {
45         my($fh, $is_new, $fn) = PAR::_tempfile("tpsaber.ico");
46         my $data = PAR::read_file("resources/tpsaber.ico");
47         print $fh $data;
48         close $fh;
49         $fn;
50     } : "resources/tpsaber.ico";
51
52 my $icon = Win32::GUI::Icon->new($icon_file);
53 my $notify_icon = $main->AddNotifyIcon(
54     -name => 'NI', -id => 1,
55     -icon => $icon, -tip => 'ThinkPad Saber',
56 );
57
58 my $popup = Win32::GUI::Menu->new(
59     "" => "SystemMenu",
60     ">&Exit" => "Exit",
61 );
62
63 sub NI_RightClick {
64     my($x, $y) = Win32::GUI::GetCursorPos();
65     $main->TrackPopupMenu($popup->{SystemMenu}, $x, $y);
66     -1;
67 }
68
69 sub Exit_Click {
70     Win32::Sound::Play('sound/off0.wav');
71     exit;
72 }
73
74 sub get_pos {
75     my $file = createFile("//./ShockMgr", "r ke") or die "Can't get ShockMgr device";
76     DeviceIoControl($file, 0x733fc, [], 0, my($buf), 0x24, my($bytes), []);
77     my @data = unpack "x4s*", $buf;
78     return @data[1, 0];
79 }
80
81 # main program
82 Win32::Sound::Volume(65535, 65535);
83 Win32::Sound::Play('sound/start0.wav');
84
85 Win32::Sound::Play('sound/idle1.wav', SND_LOOP|SND_ASYNC);
86
87 my $depth = 8;
88
89 my(@xhist, @yhist);
90
91 for (1..$depth) {
92     my($x, $y) = get_pos;
93     push @xhist, $x;
94     push @yhist, $y;
95 }
96
97 my $curr = 0;
98 my $mode = 1; # 1 = UP, 0 = DOWN
99
100 while (my($x, $y) = get_pos) {
101     shift @xhist; shift @yhist;
102     push @xhist, $x; push @yhist, $y;
103
104     my $xdev = stddev(@xhist);
105     my $ydev = stddev(@yhist);
106
107     my $dev = max($xdev, $ydev);
108     if ($mode == 1) {
109         if ($dev > $curr) {
110             $curr = $dev;
111         } else {
112             if ($dev > $threshold) {
113                 play_sound($dev);
114             }
115             $mode = 0;
116         }
117     } else {
118         if ($dev > $curr) {
119             $curr = $dev;
120             $mode = 1;
121         } else {
122             $curr = $dev;
123         }
124     }
125    
126     warn "$mode $dev" if $debug;
127     Win32::GUI::DoEvents();
128    
129     my $idle = int(rand 100) % 2 ? 1 :0;
130     Win32::Sound::Play("sound/idle$idle.wav", SND_NOSTOP|SND_LOOP|SND_ASYNC);
131     sleep 0.05;
132 }
133
134 my %par_tmp;
135
136 sub play_sound {
137     my $volume = shift;
138    
139     my $hit = $volume > 10 ? "hit" : "swing";
140     my $num = int rand ($hit ? 5 : 8);
141     my $filename = "$hit$num.wav";
142 #    $volume = int(65535 * min($volume / 15, 1));
143     warn "playing $filename in $volume" if $debug;
144 #    Win32::Sound::Volume($volume);
145     Win32::Sound::Play(File::Spec->catfile($cwd, "sound", $filename), SND_ASYNC);
146 }
147
148 sub stddev(@) {
149     my $sum=0;
150     my $sumsq=0;
151     my $n=$#_+1;
152     for my $v (@_) {
153         $sum += $v;
154         $sumsq += $v*$v;
155     }
156     return sqrt($n*$sumsq - $sum*$sum)/($n*($n-1));
157 }
158
Note: See TracBrowser for help on using the browser.