~waynemou/wahcade/devel

1 by Balki
Initial import
1
# -*- coding: UTF-8 -*-
2
#
3
###
4
# Application: wah!cade
5
# File:        joystick.py
6
# Description: Wah!Cade Joystick Class
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
7
# Copyright (c) 2007,2010   zerodiv, sairuk
1 by Balki
Initial import
8
###
9
#
10
# This program is free software; you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation; either version 2 of the License, or
13
# (at your option) any later version.
14
#
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU Library General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License
21
# along with this program; if not, write to the Free Software
22
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
#
24
from constants import *
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
25
from wc_common import WahCade
26
wc = WahCade()
27
1 by Balki
Initial import
28
import gtk
29
_ = gettext.gettext
30
pygame_imported = False
31
try:
32
    import pygame
33
    pygame_imported = True
34
except ImportError:
8 by Andy Balcombe
0.99pre6 - joystick and other fixes
35
    print _('Warning: pygame module not found.  Joysticks not supported')
36
1 by Balki
Initial import
37
38
class joystick:
39
    """pygame joystick class"""
8 by Andy Balcombe
0.99pre6 - joystick and other fixes
40
10 by Andy Balcombe
another joystick loop fix
41
    def __init__(self, debug=False):
1 by Balki
Initial import
42
        """initialise"""
60 by waynemou at gmail
small fixes and clean up
43
        self.debug = debug
1 by Balki
Initial import
44
        self.state = {}
45
        self.devices = {}
46
        self.ctrls = {}
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
47
        self.mw_key_events = []
1 by Balki
Initial import
48
        if pygame_imported:
49
            pygame.init()
10 by Andy Balcombe
another joystick loop fix
50
            pygame.mixer.quit()
39 by waynemou at gmail
Added artwork logging, will report missing artwork during fuzzy artwork search to wahcade.log
51
            self.prtjoy = 0
10 by Andy Balcombe
another joystick loop fix
52
            if debug:
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
53
                wc.log_msg("[PYGAME] init ok",1)
54
 
55
    # stop and start the joystick            
56
    def joy_count(self, type):
57
        self.num_joysticks = pygame.joystick.get_count()
54 by waynemou at gmail
multiple joystick device update, indentation fix
58
        for dev_num in range(0, self.num_joysticks):
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
59
            if dev_num < self.num_joysticks:
60
                self.devices[dev_num] = pygame.joystick.Joystick(dev_num)
61
                if type == 'start':
62
                    self.devices[dev_num].init()
63
                    if self.devices[dev_num].get_init:
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
64
                        wc.log_msg("[PYGAME] started joystick device: %s" % self.devices[dev_num].get_name())
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
65
                    else:
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
66
                        wc.log_msg("[PYGAME] Joystick device number: %s failed to initialise correctly" % str(dev_num))
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
67
                elif type == 'stop':
68
                    self.devices[dev_num].quit()
69
                    if self.devices[dev_num].get_init:
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
70
                        wc.log_msg("[PYGAME] Stopped joystick device number: %s" % str(dev_num))
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
71
                    else:
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
72
                        wc.log_msg("[PYGAME] Could not stop device number: %s" % str(dev_num))
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
73
                else:
74
                    return 1
75
        
1 by Balki
Initial import
76
    def use_ini_controls(self, ctrlr_ini):
8 by Andy Balcombe
0.99pre6 - joystick and other fixes
77
        """read controller ini file"""
1 by Balki
Initial import
78
        if not pygame_imported:
79
            return
80
        for mw_keys in ctrlr_ini.ini_dict.itervalues():
81
            mw_keys = mw_keys.strip(' "').split(' | ')
82
            for mw_key in mw_keys:
83
                if mw_key[:3] == "JOY":
84
                    self.state[mw_key] = 0
85
                    (dev_num, control) = mw_key.split("_", 1)
8 by Andy Balcombe
0.99pre6 - joystick and other fixes
86
                    dev_num = dev_num[3:]
1 by Balki
Initial import
87
                    self.devices[int(dev_num) - 1] = None
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
88
        self.joy_count('start')
8 by Andy Balcombe
0.99pre6 - joystick and other fixes
89
1 by Balki
Initial import
90
    def use_all_controls(self):
91
        """which joysticks"""
92
        if not pygame_imported:
93
            return
54 by waynemou at gmail
multiple joystick device update, indentation fix
94
        self.joy_count('start')
55 by waynemou at gmail
Fix for joysticks in wahcade-setup
95
        for dev_num in range(0, self.num_joysticks):
96
            num_buttons = self.devices[dev_num].get_numbuttons()
97
            for button_num in range(num_buttons):
98
                mw_key = "JOY%s_BUTTON%s" % (dev_num + 1, button_num)
99
                ctrl_name = _('Joystick %s Button %s') % (
100
                    dev_num + 1, button_num)
101
                self.state[mw_key] = 0
102
                self.ctrls[ctrl_name] = mw_key
103
            if self.devices[dev_num].get_numaxes() > 2:
104
                mw_key = "JOY%s_" % (dev_num + 1)
105
                ctrl_name = _('Joystick %s ') % (dev_num + 1)
106
                self.state[mw_key + "UP"] = 0
107
                self.state[mw_key + "DOWN"] = 0
108
                self.state[mw_key + "LEFT"] = 0
109
                self.state[mw_key + "RIGHT"] = 0
110
                self.ctrls[ctrl_name + _('Up')] = mw_key + "UP"
111
                self.ctrls[ctrl_name + _('Down')] = mw_key + "DOWN"
112
                self.ctrls[ctrl_name + _('Left')] = mw_key + "LEFT"
113
                self.ctrls[ctrl_name + _('Right')] = mw_key + "RIGHT"
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
114
    
115
    # Get the number of joysticks attached to the system
116
    # Log joystick names
117
    # Log joystick device numbers    
118
    def joy_info(self):
119
        """gather joystick information"""
55 by waynemou at gmail
Fix for joysticks in wahcade-setup
120
        for i in range(0, self.num_joysticks):
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
121
            wc.log_msg("[PYGAME] Joystick: %s" % str(pygame.joystick.Joystick(i).get_name()))
122
            wc.log_msg("[PYGAME] Device ID: %s" % str(pygame.joystick.Joystick(i).get_id()))
123
            wc.log_msg("[PYGAME] Number of axes: %s" % str(pygame.joystick.Joystick(i).get_numaxes()))
124
            wc.log_msg("[PYGAME] Number of trackballs: %s" % str(pygame.joystick.Joystick(i).get_numballs()))
125
            wc.log_msg("[PYGAME] Number of buttons: %s" % str(pygame.joystick.Joystick(i).get_numbuttons()))
126
            wc.log_msg("[PYGAME] Number of hats: %s" % str(pygame.joystick.Joystick(i).get_numhats()))
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
127
 
128
 
129
    def proc_keys(self, active_window, e, mw_key):
130
        if active_window.window:
131
            e.window = active_window.window
132
            if self.debug:
133
                wc.log_msg("[PYGAME] joystick, key-release: " + mw_key,1)
134
                    
135
    # poll joysticks
7 by Andy Balcombe
new scrolled_list and other changes
136
    def poll(self, event_cb, initial_repeat_delay=10):
1 by Balki
Initial import
137
        """poll for joystick events"""
138
        if not pygame_imported:
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
139
            if self.debug:
140
                wc.log_msg("[PYGAME] not imported, returning from poll function",1)
1 by Balki
Initial import
141
            return 0
7 by Andy Balcombe
new scrolled_list and other changes
142
        repeat_delay = 1
1 by Balki
Initial import
143
        # give pygame a chance to do its magic with the joystick
144
        pygame.event.pump()
145
        # end polling if no joysticks are found
39 by waynemou at gmail
Added artwork logging, will report missing artwork during fuzzy artwork search to wahcade.log
146
        if self.num_joysticks == 0 and self.prtjoy == 0:
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
147
            wc.log_msg("[PYGAME] No joysticks found")
39 by waynemou at gmail
Added artwork logging, will report missing artwork during fuzzy artwork search to wahcade.log
148
            self.prtjoy = 1
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
149
            return 0,
150
        else:
151
            # get the focused window or return
152
            active_window = None
153
            windows = gtk.window_list_toplevels()
154
            for window in windows:
155
                    if window.is_active():
156
                        active_window = window
157
                    if active_window == None:
158
                        return 1
159
            # check if any of our defined controls were pressed
160
            mw_key_events = []
161
            for mw_key in self.state.iterkeys():
162
                (dev_num, joy_type) = (mw_key.split("_", 1))
163
                dev_num = int(dev_num[3:]) - 1
164
                # if binding is for an unfound joystick, continue to next binding
165
                if dev_num > self.num_joysticks - 1:
166
                    continue
167
                if joy_type[:6] == "BUTTON":
168
                    button_num = joy_type[6:]
169
                    if self.devices[dev_num].get_button(int(button_num)):
170
                        self.state[mw_key] += 1
171
                        mw_key_events.append(mw_key)
172
                    elif self.state[mw_key] > 0:
173
                        self.state[mw_key] = 0
174
                        mw_key_events.append(mw_key)
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
175
                    else:
152 by waynemou at gmail
Added support for emulator specific controller profiles, add ctrlr option to emulator.ini file, tweaked joystick.py messages to stop them filling up log file
176
                        if self.debug:
177
                          wc.log_msg("[PYGAME] Button Not Found %s" % self.devices[dev_num].get_button(int(button_num)))
178
                        else:
179
                          pass
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
180
                elif joy_type in ["LEFT", "RIGHT", "UP", "DOWN"]:
181
                    if joy_type in ["LEFT", "RIGHT"]:
182
                        axis_num = 0
183
                    else:
184
                        axis_num = 1
185
                    axis_value = self.devices[dev_num].get_axis(axis_num)
186
                    if joy_type in ["UP", "LEFT"]:
187
                        if axis_value < -0.5:
188
                            self.state[mw_key] += 1
189
                            mw_key_events.append(mw_key)
190
                        elif self.state[mw_key] > 0:
191
                            self.state[mw_key] = 0
192
                            mw_key_events.append(mw_key)
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
193
                        else:
152 by waynemou at gmail
Added support for emulator specific controller profiles, add ctrlr option to emulator.ini file, tweaked joystick.py messages to stop them filling up log file
194
                            if self.debug:
195
                              wc.log_msg("[PYGAME] Axis in UP/LEFT Error %s" % self.devices[dev_num].get_axis(axis_num))
196
                            else:
197
                              pass
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
198
                    else:
199
                        if axis_value > 0.5:
200
                            self.state[mw_key] += 1
201
                            mw_key_events.append(mw_key)
202
                        elif self.state[mw_key] > 0:
203
                            self.state[mw_key] = 0
204
                            mw_key_events.append(mw_key)
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
205
                        else:
152 by waynemou at gmail
Added support for emulator specific controller profiles, add ctrlr option to emulator.ini file, tweaked joystick.py messages to stop them filling up log file
206
                            if self.debug:
207
                              wc.log_msg("[PYGAME] Axis OTHER Error %s" % self.devices[dev_num].get_axis(axis_num))  
208
                            else:
209
                              pass
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
210
                else:
152 by waynemou at gmail
Added support for emulator specific controller profiles, add ctrlr option to emulator.ini file, tweaked joystick.py messages to stop them filling up log file
211
                    if self.debug:
212
                      wc.log_msg("[PYGAME] Undefined %s" % joy_type)
213
                    else:
214
                      pass
36 by waynemou at gmail
general: removed symlinks for graphic files, bzr branching should be possible under windows now.
215
            # send fake key-press events
216
            if len(mw_key_events) > 0:
217
                mw_key = mw_key_events[0]
218
                if self.state[mw_key] == 0:
219
                    e = gtk.gdk.Event(gtk.gdk.KEY_RELEASE)
220
                    self.proc_keys(active_window, e, mw_key)
221
                    event_cb(active_window, e, "JOYSTICK", mw_key)
222
                elif self.state[mw_key] == 1:
223
                    e = gtk.gdk.Event(gtk.gdk.KEY_PRESS)
224
                    self.proc_keys(active_window, e, mw_key)
225
                    event_cb(active_window, e, "JOYSTICK", mw_key)
226
            #try clearing event queue
227
            try:
228
                pygame.event.clear()
229
                if self.debug:
230
                    wc.log_msg("[PYGAME] Cleared pygame events",1)
231
            except:
232
                if self.debug:
233
                    wc.log_msg("[PYGAME] Could not clear PyGame event queue",1)
151 by Wayne Moulden
Clean up work on joystick.py, intermediate commit
234
            return 1