+++ /dev/null
-/*\r
- * Acess2 Mouse Driver\r
- */\r
-#define DEBUG 0\r
-#include <acess.h>\r
-#include <modules.h>\r
-#include <vfs.h>\r
-#include <fs_devfs.h>\r
-#include <api_drv_common.h>\r
-#include <api_drv_joystick.h>\r
-#include "common.h"\r
-\r
-// == CONSTANTS ==\r
-#define NUM_AXIES 2 // X+Y\r
-#define NUM_BUTTONS 5 // Left, Right, Scroll Click, Scroll Up, Scroll Down\r
-\r
-// == PROTOTYPES ==\r
-// - Internal -\r
- int PS2Mouse_Install(char **Arguments);\r
-void PS2Mouse_HandleInterrupt(Uint8 InputByte);\r
-// - Filesystem -\r
-Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
-int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
-\r
-// == GLOBALS ==\r
-void (*gpMouse_EnableFcn)(void);\r
-// - Settings\r
- int giMouse_Sensitivity = 1;\r
- int giMouse_MaxX = 640, giMouse_MaxY = 480;\r
-// - File Data\r
-Uint8 gMouse_FileData[sizeof(tJoystick_FileHeader) + NUM_AXIES*sizeof(tJoystick_Axis) + NUM_BUTTONS];\r
-tJoystick_FileHeader *gMouse_FileHeader = (void *)gMouse_FileData;\r
-tJoystick_Axis *gMouse_Axies;\r
-Uint8 *gMouse_Buttons;\r
-tJoystick_Callback gMouse_Callback;\r
- int gMouse_CallbackArg;\r
- int giMouse_AxisLimits[2];\r
-// - Internal State\r
- int giMouse_Cycle = 0; // IRQ Position\r
-Uint8 gaMouse_Bytes[4] = {0,0,0,0};\r
-// - Driver definition\r
-tVFS_NodeType gMouse_NodeType = {\r
- .Read = PS2Mouse_Read,\r
- .IOCtl = PS2Mouse_IOCtl\r
-};\r
-tDevFS_Driver gMouse_DriverStruct = {\r
- NULL, "PS2Mouse",\r
- {\r
- .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX,\r
- .Type = &gMouse_NodeType\r
- }\r
-};\r
-\r
-// == CODE ==\r
-int PS2Mouse_Install(char **Arguments)\r
-{\r
- \r
-\r
- // Set up variables\r
- gMouse_Axies = (void*)&gMouse_FileData[4];\r
- gMouse_Buttons = (void*)&gMouse_Axies[NUM_AXIES];\r
-\r
- gMouse_FileHeader->NAxies = 2; gMouse_FileHeader->NButtons = 3;\r
- gMouse_Axies[0].MinValue = -10; gMouse_Axies[0].MaxValue = 10;\r
- gMouse_Axies[1].MinValue = -10; gMouse_Axies[1].MaxValue = 10;\r
- \r
- // Initialise Mouse Controller\r
- giMouse_Cycle = 0; // Set Current Cycle position\r
- gpMouse_EnableFcn();\r
- \r
- DevFS_AddDevice(&gMouse_DriverStruct);\r
- \r
- return MODULE_ERR_OK;\r
-}\r
-\r
-/* Handle Mouse Interrupt\r
- */\r
-void PS2Mouse_HandleInterrupt(Uint8 InputByte)\r
-{\r
- Uint8 flags;\r
- int d[2], d_accel[2];\r
- int i;\r
- \r
- // Gather mouse data\r
- gaMouse_Bytes[giMouse_Cycle] = InputByte;\r
- LOG("gaMouse_Bytes[%i] = 0x%02x", gMouse_Axies[0].MaxValue);\r
- // - If bit 3 of the first byte is not set, it's not a valid packet?\r
- if(giMouse_Cycle == 0 && !(gaMouse_Bytes[0] & 0x08) )\r
- return ;\r
- giMouse_Cycle++;\r
- if(giMouse_Cycle < 3)\r
- return ;\r
-\r
- giMouse_Cycle = 0;\r
-\r
- // Actual Processing (once we have all bytes) \r
- flags = gaMouse_Bytes[0];\r
-\r
- LOG("flags = 0x%x", flags);\r
- \r
- // Check for X/Y Overflow\r
- if(flags & 0xC0) return;\r
- \r
- // Calculate dX and dY\r
- d[0] = gaMouse_Bytes[1]; if(flags & 0x10) d[0] = -(256-d[0]); // x\r
- d[1] = gaMouse_Bytes[2]; if(flags & 0x20) d[1] = -(256-d[1]); // y\r
- d[1] = -d[1]; // Y is negated\r
- LOG("RAW dx=%i, dy=%i\n", d[0], d[1]);\r
- // Apply scaling\r
- // TODO: Apply a form of curve to the mouse movement (dx*log(dx), dx^k?)\r
- // TODO: Independent sensitivities?\r
- // TODO: Disable acceleration via a flag?\r
- d_accel[0] = d[0]*giMouse_Sensitivity;\r
- d_accel[1] = d[1]*giMouse_Sensitivity;\r
- \r
- // Set Buttons (Primary)\r
- for( i = 0; i < 3; i ++ )\r
- {\r
- Uint8 newVal = (flags & (1 << i)) ? 0xFF : 0;\r
- if(newVal != gMouse_Buttons[i]) {\r
- if( gMouse_Callback )\r
- gMouse_Callback(gMouse_CallbackArg, 0, i, newVal - gMouse_Buttons[i]);\r
- gMouse_Buttons[i] = newVal;\r
- }\r
- }\r
- \r
- // Update X and Y Positions\r
- for( i = 0; i < 2; i ++ )\r
- {\r
- Sint16 newCursor = 0;\r
- if( giMouse_AxisLimits[i] )\r
- newCursor = MIN( MAX(0, gMouse_Axies[i].CursorPos + d_accel[i]), giMouse_AxisLimits[i] );;\r
- \r
- if( gMouse_Callback )\r
- {\r
- if(giMouse_AxisLimits[i] && gMouse_Axies[i].CursorPos != newCursor)\r
- gMouse_Callback(gMouse_CallbackArg, 1, i, newCursor - gMouse_Axies[i].CursorPos);\r
- if(!giMouse_AxisLimits[i] && gMouse_Axies[i].CurValue != d_accel[i])\r
- gMouse_Callback(gMouse_CallbackArg, 1, i, d_accel[i] - gMouse_Axies[i].CurValue);\r
- }\r
- \r
- gMouse_Axies[i].CurValue = d_accel[i];\r
- gMouse_Axies[i].CursorPos = newCursor;\r
- }\r
-\r
-// Log("Mouse at %ix%i", gMouse_Axies[0].CursorPos, gMouse_Axies[1].CursorPos);\r
- \r
- VFS_MarkAvaliable(&gMouse_DriverStruct.RootNode, 1);\r
-}\r
-\r
-/* Read mouse state (coordinates)\r
- */\r
-Uint64 PS2Mouse_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
-{\r
- if(Offset > sizeof(gMouse_FileData)) return 0;\r
- if(Length > sizeof(gMouse_FileData)) Length = sizeof(gMouse_FileData);\r
- if(Offset + Length > sizeof(gMouse_FileData)) Length = sizeof(gMouse_FileData) - Offset;\r
-\r
- memcpy(Buffer, &gMouse_FileData[Offset], Length);\r
- \r
- VFS_MarkAvaliable(Node, 0);\r
- return Length;\r
-}\r
-\r
-static const char *csaIOCtls[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};\r
-/* Handle messages to the device\r
- */\r
-int PS2Mouse_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
-{\r
- tJoystick_NumValue *info = Data;\r
-\r
- switch(ID)\r
- {\r
- BASE_IOCTLS(DRV_TYPE_JOYSTICK, "PS2Mouse", 0x100, csaIOCtls);\r
-\r
- case JOY_IOCTL_SETCALLBACK: // TODO: Implement\r
- return -1;\r
- \r
- case JOY_IOCTL_SETCALLBACKARG: // TODO: Implement\r
- return -1;\r
- \r
- case JOY_IOCTL_GETSETAXISLIMIT:\r
- if(!info) return 0;\r
- if(info->Num < 0 || info->Num >= 2) return 0;\r
- if(info->Value != -1)\r
- giMouse_AxisLimits[info->Num] = info->Value;\r
- return giMouse_AxisLimits[info->Num];\r
- \r
- case JOY_IOCTL_GETSETAXISPOSITION:\r
- if(!info) return 0;\r
- if(info->Num < 0 || info->Num >= 2) return 0;\r
- if(info->Value != -1)\r
- gMouse_Axies[info->Num].CursorPos = info->Value;\r
- return gMouse_Axies[info->Num].CursorPos;\r
-\r
- case JOY_IOCTL_GETSETAXISFLAGS:\r
- return -1;\r
- \r
- case JOY_IOCTL_GETSETBUTTONFLAGS:\r
- return -1;\r
-\r
- default:\r
- return 0;\r
- }\r
-}\r
-\r