coreBugZJ

此 blog 已弃。

将游戏手柄操作映射为鼠标操作

/*
JoyToMouse.c

Copyright (C) 2011, coreBugZJ, all rights reserved.

版本:
1.0.0

功能:
将游戏手柄操作映射为鼠标操作。

原理:
接收手柄消息,然后产生相应鼠标消息。

使用:
方向键移动(会自动加速);
键 1 <==> 左键;
键 2 <==> 右键;

键 3 <==> 调整灵敏度,增加;
键 4 <==> 调整灵敏度,减小。

*/


#include <Windows.h>
#include <MMSystem.h>


#pragma comment( lib, "winmm.lib" )


        /* 每 ELAPSE 毫秒检测手柄输入 */
#define  ELAPSE    17

        /* 速度     mickeys / ELAPSE */
INT  BASE_VX = 4;
INT  BASE_VY = 4;
        /* 加速度   mickeys / ELAPSE / ELAPSE */
INT  ACCEL_VX   = 8;
INT  ACCEL_VY   = 8;
        /* 加加速度 mickeys / ELAPSE / ELAPSE / ELAPSE */
#define  ACCEL_ACCEL_VX    1
#define  ACCEL_ACCEL_VY    1
        /* 方向标志 */
#define  MASK_LEFT      ((DWORD)1)
#define  MASK_RIGHT     ((DWORD)2)
#define  MASK_UP        ((DWORD)4)
#define  MASK_DOWN      ((DWORD)8)


TCHAR gClassName[] = TEXT("JoyToMouse");
TCHAR gWndName[]   = TEXT("JoyToMouse -- coreBugZJ");


VOID msgOut( HWND hWnd, TCHAR msg[], UINT msglen ) {
        HDC hdc = GetDC( hWnd );
        TextOut( hdc, 50, 20, msg, msglen );
        ReleaseDC( hWnd, hdc );

        /* MessageBox( NULL, msg, msg, MB_OK ); */
}


LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
        static JOYINFO  ji1;
        static DWORD    id1 = 0xFFFF;
        static JOYCAPS  jc1;
        static DWORD    numDev;
        static DWORD    jxm1, jxl1, jxr1, jym1, jyt1, jyb1, x1, y1;
        static DWORD    dirMask = 0;
        static INT      vx = 0, vy = 0;

        INT      dx, dy;
        DWORD    bf;

        switch ( uMsg ) {
        case WM_CREATE :
                SetTimer( hWnd, 1, ELAPSE, NULL );

                if ( 0 == (numDev = joyGetNumDevs()) ) {
                        MessageBox( hWnd, TEXT("0 == joyGetNumDevs()\n\n请检查手柄是否插好"), TEXT("Error"), MB_OK | MB_ICONERROR );
                        SendMessage( hWnd, WM_DESTROY, 0, 0 );
                        return 0;
                }

                // 手柄 1
                if ( JOYERR_NOERROR != joyGetPos( JOYSTICKID1, &ji1 ) ) {
                        MessageBox( hWnd, TEXT("JOYERR_NOERROR != joyGetPos()\n\n请检查手柄是否插好"), TEXT("Error"), MB_OK | MB_ICONERROR );
                        SendMessage( hWnd, WM_DESTROY, 0, 0 );
                        return 0;
                }
                if ( JOYERR_NOERROR != joyGetDevCaps( JOYSTICKID1, &jc1, sizeof(jc1) ) ) {
                        MessageBox( hWnd, TEXT("JOYERR_NOERROR != joyGetDevCaps()\n\n请检查手柄是否插好"), TEXT("Error"), MB_OK | MB_ICONERROR );
                        SendMessage( hWnd, WM_DESTROY, 0, 0 );
                        return 0;
                }
                id1  = JOYSTICKID1;
                jxm1 = ( jc1.wXmin + jc1.wXmax ) / 2;
                jxl1 = ( jc1.wXmin + jxm1 ) / 2;
                jxr1 = ( jc1.wXmax + jxm1 ) / 2;
                jym1 = ( jc1.wYmin + jc1.wYmax ) / 2;
                jyt1 = ( jc1.wYmin + jym1 ) / 2;
                jyb1 = ( jc1.wYmax + jym1 ) / 2;
                x1   = jxm1;
                y1   = jym1;
                joySetCapture( hWnd, id1, ELAPSE, TRUE );
                return 0;

        case WM_TIMER :
                if ( 0 == dirMask ) {
                        return 0;
                }

                dx = dy = 0;
                if ( dirMask & MASK_LEFT ) {
                        vx += ACCEL_VX;
                        dx  = -vx;
                }
                if ( dirMask & MASK_RIGHT ) {
                        vx += ACCEL_VX;
                        dx  = vx;
                }
                if ( dirMask & MASK_UP ) {
                        vy += ACCEL_VY;
                        dy  = -vy;
                }
                if ( dirMask & MASK_DOWN ) {
                        vy += ACCEL_VY;
                        dy  = vy;
                }

                msgOut( hWnd, TEXT("MOVE         "), 12 );
                mouse_event( MOUSEEVENTF_MOVE, dx, dy, 0, 0 );
                return 0;

        case MM_JOY1MOVE :
                dirMask = 0;
                x1 = LOWORD(lParam);
                y1 = HIWORD(lParam);
                if ( x1 < jxl1 ) {
                        dirMask |= MASK_LEFT;
                        vx = BASE_VX;
                        msgOut( hWnd, TEXT("LEFT1 DOWN   "), 12 );
                }
                if ( x1 > jxr1 ) {
                        dirMask |= MASK_RIGHT;
                        vx = BASE_VX;
                        msgOut( hWnd, TEXT("RIGHT1 DOWN  "), 12 );
                }
                if ( y1 < jyt1 ) {
                        dirMask |= MASK_UP;
                        vy = BASE_VY;
                        msgOut( hWnd, TEXT("UP1 DOWN     "), 12 );
                }
                if ( y1 > jyb1 ) {
                        dirMask |= MASK_DOWN;
                        vy = BASE_VY;
                        msgOut( hWnd, TEXT("DOWN1 DOWN   "), 12 );
                }
                return 0;

        case MM_JOY1BUTTONDOWN :
                bf = wParam;
                if ( (bf & JOY_BUTTON1CHG) && (bf & JOY_BUTTON1) ) {
                        mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
                        msgOut( hWnd, TEXT("BTN11 DOWN   "), 12 );
                }
                if ( (bf & JOY_BUTTON2CHG) && (bf & JOY_BUTTON2) ) {
                        mouse_event( MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0 );
                        msgOut( hWnd, TEXT("BTN12 DOWN   "), 12 );
                }
                if ( (bf & JOY_BUTTON3CHG) && (bf & JOY_BUTTON3) ) {
                        ACCEL_VX += ACCEL_ACCEL_VX;
                        ACCEL_VY += ACCEL_ACCEL_VY;
                        BASE_VX  += ACCEL_VX;
                        BASE_VY  += ACCEL_VY;
                        msgOut( hWnd, TEXT("BTN13 DOWN   "), 12 );
                }
                if ( (bf & JOY_BUTTON4CHG) && (bf & JOY_BUTTON4) ) {
                        BASE_VX  -= ACCEL_VX;
                        BASE_VY  -= ACCEL_VY;
                        if ( BASE_VX < 1 ) {
                                BASE_VX = 1;
                        }
                        if ( BASE_VY < 1 ) {
                                BASE_VY = 1;
                        }
                        ACCEL_VX -= ACCEL_ACCEL_VX;
                        ACCEL_VY -= ACCEL_ACCEL_VY;
                        if ( ACCEL_VX < 0 ) {
                                ACCEL_VX = 0;
                        }
                        if ( ACCEL_VY < 0 ) {
                                ACCEL_VY = 0;
                        }
                        msgOut( hWnd, TEXT("BTN14 DWON   "), 12 );
                }
                return 0;

        case MM_JOY1BUTTONUP :
                bf = wParam;
                if ( (bf & JOY_BUTTON1CHG) && (0 == (bf & JOY_BUTTON1)) ) {
                        mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
                        msgOut( hWnd, TEXT("BTN11 UP     "), 12 );
                }
                if ( (bf & JOY_BUTTON2CHG) && (0 == (bf & JOY_BUTTON2)) ) {
                        mouse_event( MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0 );
                        msgOut( hWnd, TEXT("BTN12 UP     "), 12 );
                }
                if ( (bf & JOY_BUTTON3CHG) && (0 == (bf & JOY_BUTTON3)) ) {
                        msgOut( hWnd, TEXT("BTN13 UP    "), 12 );
                }
                if ( (bf & JOY_BUTTON4CHG) && (0 == (bf & JOY_BUTTON4)) ) {
                        msgOut( hWnd, TEXT("BTN14 UP     "), 12 );
                }
                return 0;

        case WM_DESTROY :
                KillTimer( hWnd, 1 );
                if ( JOYSTICKID1 == id1 ) {
                        joyReleaseCapture( id1 );
                }
                PostQuitMessage( 0 );
                return 0;
        }

        return DefWindowProc( hWnd, uMsg, wParam, lParam );
}


INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmd, INT nShow ) {
        WNDCLASSEX  wc;
        HWND        hWnd;
        MSG         msg;

        wc.cbClsExtra    = 0;
        wc.cbSize        = sizeof(wc);
        wc.cbWndExtra    = 0;
        wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
        wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
        wc.hIcon         = LoadIcon( NULL, IDI_APPLICATION );
        wc.hIconSm       = LoadIcon( NULL, IDI_APPLICATION );
        wc.hInstance     = hInst;
        wc.lpfnWndProc   = WndProc;
        wc.lpszClassName = gClassName;
        wc.lpszMenuName  = NULL;
        wc.style         = 0;

        if ( 0 == RegisterClassEx( &wc ) ) {
                MessageBox( NULL, TEXT("RegisterClassEx Failed!"), TEXT("Error"), MB_OK | MB_ICONERROR );
                return 0;
        }

        hWnd = CreateWindowEx( 0,
                gClassName, gWndName,
                WS_OVERLAPPEDWINDOW,
                200, 200, 400, 100,
                NULL, NULL,
                hInst, NULL );
        if ( NULL == hWnd ) {
                MessageBox( NULL, TEXT("CreateWindowEx Failed!"), TEXT("Error"), MB_OK | MB_ICONERROR );
                return 0;
        }
        ShowWindow( hWnd, nShow );
        UpdateWindow( hWnd );

        while ( GetMessage( &msg, NULL, 0, 0 ) ) {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
        }
        return msg.wParam;
}

posted on 2011-12-31 16:41 coreBugZJ 阅读(2088) 评论(0)  编辑 收藏 引用 所属分类: 娱乐


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理