Linux Joystick HOWTO

작성자: 차영호 (ganadist@dacome.co.kr)
이 문서는 잘못된 정보를 포함할수도 있습니다. 잘못된 부분이 있다면 주저말고 메일 주십시오.
이 문서는 누구나 편집 재배포가 가능합니다.

1. 필요한것.


사운드 카드, 조이스틱, 그리고 리눅스 박스 ^^
 

2. 보아 두어야 할것


ldp에 암만 뒤벼봐두 없습니다. 이미 커널문서에 포함되어 있어서 그런게 아닌가 싶네요.

/usr/src/linux/Documentation/joystick.txt에 보면 아주 상세히 나와 있습니다.

but, 울나라 국민들이 영어에 약한분들이 많아서, 저의 미약한 실력으로 제 경험담과 함께 묶어서 쉽게 얘기 해보도록 하겠습니다.
 

3. 조이스틱 잡는방법


일단 커널에 조이스틱 모듈이 컴파일 되어있는지 봅니다.

조이스틱 모듈이 들어있는 디렉토리는 /lib/modules/커널버젼/misc에 있습니다

이름은 joy로 시작하는 파일들입니다.

없으면 커널을 다시 컴파일 하시면 됩니다. (커널 컴파일에 대해서는 생략하겠습니다.) 파일 이름들을 보시면 아시겠지만 joy-스틱이름 입니다.. 만약 해당하는 스틱이 있다면 몇몇기종을 제외하고는 바로 잡힌다고 문서에 나와있습니다.

그냥 단순히 modprobe 모듈이름 하시면 됩니다

modprobe joy-sidewinder

이런식으로 말이죠.

하지만 이렇게 비싼 스틱을 사용하는 가난한 리눅서분들은 없을듯 합니다.

가장일반적으로 많이 쓰이는게 joy-analog 와 joy-pci 입니다.

joy-analog는 보통 사블계열의 사운드카드에 싸구려 조이스틱을 사용할때 이걸 쓰시면 되구 joy-pci는 pci사운드카드(트라이던트 4wave, 오리얼 보텍스등등)에서 싸구려 조이스틱을 사용할 때 쓰면 됩니다.

하지만 그냥 해서는 제대로 잡히지 않습니다.

조이스틱의 종류가 워낙 다양해서죠..

2축,3축 2버튼,4버튼,8버튼, 게다가 스로틀 까지..  그에 따라 적당한 옵션을 넣어야 합니다.

우리가 고칠곳은 당연히 conf.modules입니다.

저의 설정은 이렇게 되어 있습니다.

alias char-major-15 joy-analog
options joy-analog js_an=0x201,12531,0

여기에서 중요한것은 12531이라는 숫자 입니다.

이 숫자가 커널에 이 조이스틱이 버튼몇개가 있고 축이 몇개가 있고 등등을 전달하는 인수가 됩니다.

이 숫자만 만드는 방법을 알고 있으면 이 문서의 핵심을 하는것이 됩니다.

커널문서에 의하면 다음과 같습니다

        Bit |   2^n | Meaning
        ----------------------------------
         0  |     1 | Axis X1  (1축)
         1  |     2 | Axis Y1  (2축)
         2  |     4 | Axis X2  (3축)
         3  |     8 | Axis Y2  (4축)
         4  |    16 | Button A (1버튼)
         5  |    32 | Button B  (2버튼)
         6  |    64 | Button C  (3버튼)
         7  |   128 | Button D  (4버튼)
         8  |   256 | CHF Buttons X and Y
         9  |   512 | CHF Hat 1
        10  |  1024 | CHF Hat 2
        11  |  2048 | FCS Hat
        12  |  4096 | Pad Button X (5버튼)
        13  |  8192 | Pad Button Y (6버튼)
        14  | 16384 | Pad Button U (7버튼)
        15  | 32768 | Pad Button V (8버튼)

저의 조이스틱 같은 경우에는 2축 6버튼 입니다.

계산은 다음과 같이 합니다

1축+2축+1버튼+2버튼+3버튼+4버튼+5버튼+6버튼
= 0x0001+0x0002+0x0010+0x0020+0x0040+0x0080+0x1000+0x2000
=0x30F3 = 12531

0x는 16진수를 가르킵니다.  물론 인수로 10진수 말고도 16진수로도 가능합니다.

만약 2축 4버튼이면 4버튼까지만 계산하면 되겠죠.

1축+2축+1버튼+2버튼+3버튼+4버튼
= 0x0001+0x0002+0x0010+0x0020+0x0040+0x0080
=0x00F3 = 243 이 됩니다.

자. 이제 이것을 conf.modules에 포함시킵니다.

alias char-major-15 joy-analog
options joy-analog js_an=0x201,0x30f3,0

맨앞은 조이스틱 디바이스를 얼라이싱 하는것입니다.

/dev/js*를 보면 아시겠지만

디바이스 노드가 캐릭터 디바이스의  메이저숫자가 15로 되어있습니다.

이 디바이스에 억세스 할려고 하면 자동으로 모듈을 띄운다는 뜻이죠.

그다음에는 이 모듈을 띄울때 다음과 같은 옵션(인자)를 넣어 줍니다.

인자로는 이것은 아날로그 조이스틱이므로 js_an이라는 이름이 들어가고 그뒤에 조이스틱포트이 io주소, 위에서 실컷 설명한 조이스틱인자, 그리고 정체불명의 0이라는 숫자가 들어가 있습니다(아시는분 있으면 연락주세요 ^^)

만약 조이스틱이 2개이면

options joy-analog js_an=0x201,0x30f3,0,0x202,0x00f3,0

이런식으로 계속 연결해주면 됩니다 물론 같은 아날로그 조이스틱일때죠.

이렇게 conf.modules를 편집한뒤 저장하고

modprobe joy-analog

를 실행하고나서 lsmod를 치면

[root@ganadist Documentation]# lsmod
Module                  Size  Used by
joy-analog              4664   0  (unused)
joystick                5852   0  [joy-analog]

가 보일껍니다.

그리고 정확하게 세팅되었는지 볼려면 dmesg로 커널메세지를 확인해보면 됩니다.

[root@ganadist Documentation]# dmesg

    ...................
js: Joystick driver v1.2.15 (c) 1999 Vojtech Pavlik <vojtech@suse.cz>
js0: Analog 2-axis 6-button joystick with XY/UV extensions at 0x201 [TSC timer, 350 MHz clock, 1505 ns res]

아래에 2축 6버튼이라고 잡히는거 보이시죠?
 

4. 조이스틱 설정 확인


리눅스의 조이스틱 모듈은 수세 리눅스  에서 개발중입니다. 거기서 모듈을 받으시면 모듈이외에도 조이스틱의 설정을 확인할수 있는 유틸들이 있습니다.
(소스를 컴파일 하기  힘드시면 rpm으로 된것은 여기에서 얻을수 있습니다 . 꾸러미를 만들어주신 황상진님께 감사 ^^)

jsattatch, jscal, jstest 죠.

jsattach는 시리얼라인으로 부착되는 (비싼겁니다. -.-a) 조이스틱들을 세팅할때 쓰는거라는군요.

우리가 유심히 봐야 할 부분은 jscal과 jstest입니다.

jscal은 조이스틱 감도를 조절(calibration라고 하죠)하는 유틸이고 jstest는 말 그대로 테스트를 해볼때 쓰입니다.

jscal -c /dev/js0 은 감도를 세팅하는 것입니다.

jscal -p /dev/js0은 현재 감도를 출력하는 것입니다.

먼저 세팅을 한 다음에 -p옵션으로 나오는 문자를 파일로 저장합니다.

[root@ganadist test]# jscal -p /dev/js0
jscal -s 2,1,6,549,551,1020636,985054,1,10,561,567,997871,999729 /dev/js0

리다이렉션을 이용해서 파일로 저장하면 되겠죠?

[root@ganadist test]# jscal -p /dev/js0 > /etc/joystick.conf

그다음에 rc.local같은 스크립트에 맨 마지막에 다음과 같이 해주면..

source /etc/joystick.conf

하면 부팅하면서 자동으로 세팅 끝내 주겠죠?

jstest /dev/js0 하면

각축과 버튼들을 테스트 해볼수 있습니다.
 

5. 조이스틱 활용하기.


자. 적은김에 뽕을 뽑겠습니다. -.-a
 

1) mame에서 조이스틱 사용하기


makefile.unix에서 다음 부분을 수정합니다.

Input Devices섹션에서 주석처리된 부분을 지웁니다.
 

# Select one or more joystick types which you want to use, which one is
# actually used can be selected runtime with the -joytype switch.

# *** for using X Input Extensions based joystick
# This is known to not work right now ;)
# ( Recommended if available. Of course: doesn't work in SVGALib arch ...)
# You should also declare a default name for input device.
# and choose polling method ( event processing or device polling )
# use provided program "xlistdev" to now available ones
# and dont forget to include library in linker definition !!
 JSX11   = -DX11_JOYSTICK
 JSNAME = \"Joystick\"
 JSPOLL  = -DUSE_X11_JOYEVENTS
 JSLIB   = -lXi

# On iX86 based OS's, if supported, you can use standard joystick driver
 JSI386 = -DI386_JOYSTICK

위는 엑스윈도에서 조이스틱을 세팅하고나서 사용하는것을 뜻하고 아래는 커널에서 제공하는 모듈을 사용하는 것입니다.

그다음 컴파일을 하고나서 xmamerc 를 수정합니다.

# what kind of joystick to use, if any
# 0 No joystick
# 1 i386 style joystick driver (if compiled in)
# 2 Fm Town Pad support (if compiled in)
# 3 X11 input extension joystick (if compiled in)
# 4 new i386 linux 1.x.x joystick driver (if compiled in)
joytype         4

# Is your joystick analog?
analogstick     1

# If using X11 based joystick enter name of joystick device
# Use provided "xlistdev" command, to see which one are availables
# on your system
#x11joyname     Joystick

커널 2.2에서 사용되는 모듈은 4번째 타입으로 설정 하면 됩니다.

(여간하면 엑스에서 세팅하여 mame돌리지 마십시오 열 받습니다 ^^)

자  세팅 끝나고 xmame를 실행하면 조이스틱이 잡혔다고 메세지가 뜹니다.

[root@ganadist xmame]# xmame.x11
Linux Sound Driver initialization...
Setting fragsize to 4096, numfrags to 5
Fragsize = 4096, Numfrags = 5
Audio device /dev/dsp set to 16bit linear stereo 44100Hz
Mouse/Trakball selected.
Using a Visual with a depth of 16bpp.
MIT-SHM Extension Available. trying to use... Success.
Using Shared Memory Features to speed up
Actual bits per pixel = 16... Ok
I386 joystick interface initialization...
Joystick: /dev/js0 is Analog 2-axis 6-button joystick with XY/UV extensions
Joystick: Built in driver version: 1.2.15
Joystick: Kernel driver version  : 1.2.15
OSD: Info: Joystick 0, 2 axis, 6 buttons
width= 256, height = 256, viswidth = 256, visheight = 224,visstartx= 0, visstarty= 16
Game uses 254 colors
 

2) 엑스윈도에서 조이스틱 사용하기


XF86Config 파일의 맨 끝부분에 다음과 같이 추가 합니다.
 

Section "Module"
    Load "xf86Jstk.so"
    Load "xie.so"
EndSection
# **********************************************************************
# Input devices
# **********************************************************************
Section "Xinput"
       SubSection "Joystick"
               Port "/dev/js0"
               DeviceName "Joystick"
               TimeOut 10
               MinimumXPosition 1
               MaximumXPosition 255
               MinimumYPosition 1
               MaximumYPosition 255
               CenterX 128
               CenterY 128
               Delta 20
                      AlwaysCore
       EndSubSection
EndSection

다시 엑스를 구동하면 조이스틱을 포인터디바이스로 사용할수 있습니다.
(그냥 심심하면 해보세요.. 그리 할짓은 못됩니다만.. -.-a)
 

6. 부록: 조이스틱 설정 스크립트

부족한 실력이라도 한번 대충 만들어 봤습니다. 아직 완성된것은 아닙니다만 그럭저럭 쓸만은 합니다.

해보고나니 남는거두 많군요 ^^ (첨으로 awk라는걸 써봤습니다 )

===============================
#!/bin/sh
 

JOY_CONF=/etc/conf.modules
cp -f ${JOY_CONF} ${JOY_CONF}.bak
grep -v joy ${JOY_CONF} > ${JOY_CONF}.tmp

case "${LANG}" in
    ko | korean | ko_KR | ko_KR.eucKR )
        intro="어떤 종류의 조이스틱을 가지고 있습니까?"
        select_item="1) 아나로그 2) PCI 3) 그외  기본값)아나로그"
        select_axis="1)1축 2)2축 3)3축 4)4축 기본값)2축"
        select_btn="1)2버튼 2)4버튼 3)6버튼 4)8버튼 기본값)4버튼"
        success="" ;;
    * )
        intro="What type of Joystick do you have?"
        select_item="1) analog 2) pci 3) etc  default)analog"
        select_axis="1)1 axis 2)2 axis 3)3 axis 4)4 axis  default)2 axis"
        select_btn="1)2 button 2)4 button 3)6 button 4)8 button default)4 button" ;;
esac
echo $intro
echo $select_item
read type
case "${type}" in
    1 ) JOY_TYPE=analog
        SHORT=an;;
    2 ) JOY_TYPE=pci
        SHORT=pci;;
    3 ) ;;
    * ) JOY_TYPE=analog
        SHORT=an
esac
echo $select_axis
read type
case "${type}" in
    1 ) AXIS=1 ;;
    2 ) AXIS=3 ;;
    3 ) AXIS=7 ;;
    4 ) AXIS=15 ;;
    * ) AXIS=3
esac
echo $AXIS
echo $select_btn
read type
case "${type}" in
    2 ) BTN=240 ;;
    3 ) BTN=12528 ;;
    4 ) BTN=61680 ;;
    * ) BTN=240
esac
echo $BTN

echo "alias char-major-15 joy-${JOY_TYPE}" >> ${JOY_CONF}.tmp
echo "options joy-${JOY_TYPE} js_${SHORT}=0x201,$(($AXIS + $BTN)),0" >> ${JOY_CONF}.tmp

for MODULE in $(lsmod |grep joy | awk '{ printf("\n"$1) }')
do
    rmmod $MODULE
done
mv -f ${JOY_CONF}.tmp ${JOY_CONF}
modprobe joy-${JOY_TYPE}
dmesg | tail -n 2

============================================
 
 

조이스틱 하우투 끄으읕~