FUNCTION ufix8 FONTFAR *plaid_tcb( GDECL ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ ufix8 format) /* Character format byte */ /* * Called by make_simp_char() and make_comp_char() to set up the controlled * coordinate table and skip all other intelligent scaling rules embedded * in the character data. * Updates pointer to first byte after plaid data. * This is used only if intelligent scaling is not supported in the * configuration definitions. */ { fix15 i, n; sp_globals.no_X_orus = (format & BIT2)? (fix15)NEXT_BYTE(pointer): 0; sp_globals.no_Y_orus = (format & BIT3)? (fix15)NEXT_BYTE(pointer): 0; pointer = read_oru_table(pointer); /* Updates no_X/Y/orus */ sp_globals.Y_edge_org = sp_globals.no_X_orus; /* Skip over control zone table */ pointer = skip_control_zone(pointer,format); /* Skip over interpolation table */ pointer = skip_interpolation_table(pointer,format); return pointer; }
FUNCTION ufix8 FONTFAR *skip_interpolation_table( GDECL ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ ufix8 format) /* Character format byte */ { fix15 i,n; ufix8 intsize[9]; intsize[0] = 1; intsize[1] = 2; intsize[2] = 3; intsize[3] = 1; intsize[4] = 2; intsize[5] = 1; intsize[6] = 2; intsize[7] = 0; intsize[8] = 0; n = ((format & BIT6)? (fix15)NEXT_BYTE(pointer): 0); n += ((format & BIT7)? (fix15)NEXT_BYTE(pointer): 0); for (i = 0; i < n; i++) /* For each entry in int table ... */ { format = NEXT_BYTE(pointer); /* Read format byte */ if (format & BIT7) /* Short Start/End point spec? */ { pointer++; /* Skip Start/End point byte */ } else { pointer += intsize[format & 0x7]; /* Skip Start point spec */ pointer += intsize[(format >> 3) & 0x7]; /* Skip End point spec */ } } return pointer; }
FUNCTION ufix8 FONTFAR *plaid_tcb( GDECL ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ ufix8 format) /* Character format byte */ /* * Called by make_simp_char() and make_comp_char() to set up the controlled * coordinate table and process all intelligent scaling rules embedded * in the character data. * Updates pointer to first byte after plaid data. * This is used only if intelligent scaling is enabled in the * configuration definitions. */ { fix15 no_X_ctrl_zones; fix15 no_Y_ctrl_zones; fix15 no_X_int_zones; fix15 no_Y_int_zones; #if INCL_PLAID_OUT /* Plaid data monitoring included? */ begin_plaid_data(); #endif sp_constr_update(); /* Update constraint table if required */ sp_globals.no_X_orus = (format & BIT2)? (fix15)NEXT_BYTE(pointer): 0; sp_globals.no_Y_orus = (format & BIT3)? (fix15)NEXT_BYTE(pointer): 0; pointer = read_oru_table(pointer); /* Updates no_X/Y/orus to include zero values */ sp_globals.Y_edge_org = sp_globals.no_X_orus; if (sp_globals.no_X_orus > 1) /* 2 or more controlled X coordinates? */ sp_globals.tcb.xmode = sp_globals.tcb.xtype; /* Enable intelligent scaling in X */ if (sp_globals.no_Y_orus > 1) /* 2 or more controlled Y coordinates? */ sp_globals.tcb.ymode = sp_globals.tcb.ytype; /* Enable intelligent scaling in Y */ no_X_ctrl_zones = sp_globals.no_X_orus - 1; no_Y_ctrl_zones = sp_globals.no_Y_orus - 1; pointer = sp_setup_pix_table(pointer, (boolean)(format & BIT4), no_X_ctrl_zones, no_Y_ctrl_zones); no_X_int_zones = (format & BIT6)? (fix15)NEXT_BYTE(pointer): 0; no_Y_int_zones = (format & BIT7)? (fix15)NEXT_BYTE(pointer): 0; sp_globals.Y_int_org = no_X_int_zones; pointer = sp_setup_int_table(pointer, no_X_int_zones, no_Y_int_zones); #if INCL_PLAID_OUT /* Plaid data monitoring included? */ end_plaid_data(); #endif return pointer; }
/***************************************************************************** * * @doc EXTERNAL * * @func NTSTATUS | HGM_GenerateReport | * * Generates a hid report descriptor for a n-axis, m-button joystick, * depending on number of buttons and joy_hws_flags field. * * @parm IN PDEVICE_OBJECT | DeviceObject | * * Pointer to the device object * * @parm IN OUT UCHAR * | rgGameReport[MAXBYTES_GAME_REPORT] | * * Array that receives the HID report descriptor * * @parm OUT PUSHORT | pCbReport | * * Address of a short integer that receives size of * HID report descriptor. * * @rvalue STATUS_SUCCESS | success * @rvalue STATUS_BUFFER_TOO_SMALL | Need more memory for HID descriptor * *****************************************************************************/ NTSTATUS INTERNAL HGM_GenerateReport ( IN PDEVICE_OBJECT DeviceObject, OUT UCHAR rgGameReport[MAXBYTES_GAME_REPORT], OUT PUSHORT pCbReport ) { PDEVICE_EXTENSION DeviceExtension; NTSTATUS ntStatus; UCHAR *pucReport; int Idx; UCHAR numaxes; PAGED_CODE(); DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject); pucReport = rgGameReport; #define NEXT_BYTE( pReport, Data ) \ *pReport++ = Data; #define NEXT_LONG( pReport, Data ) \ *(((LONG UNALIGNED*)(pReport))++) = Data; #define ITEM_DEFAULT 0x00 /* Data, Array, Absolute, No Wrap, Linear, Preferred State, Has no NULL */ #define ITEM_VARIABLE 0x02 /* as ITEM_DEFAULT but value is a variable, not an array */ #define ITEM_HASNULL 0x40 /* as ITEM_DEFAULT but values out of range are considered NULL */ #define ITEM_ANALOG_AXIS ITEM_VARIABLE #define ITEM_DIGITAL_POV (ITEM_VARIABLE|ITEM_HASNULL) #define ITEM_BUTTON ITEM_VARIABLE #define ITEM_PADDING 0x01 /* Constant (nothing else applies) */ switch(DeviceExtension->psx.type) { case 0: case 1: case 2: numaxes = 4; break; case 9: numaxes = 3; break; default: numaxes = 2; }; /* USAGE_PAGE (Generic Desktop) */ NEXT_BYTE(pucReport, HIDP_GLOBAL_USAGE_PAGE_1); NEXT_BYTE(pucReport, HID_USAGE_PAGE_GENERIC); /* USAGE (Joystick | GamePad ) */ NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_GAMEPAD); /* Logical Min is the smallest value that could be produced by a poll */ NEXT_BYTE(pucReport, HIDP_GLOBAL_LOG_MIN_1); NEXT_BYTE(pucReport, 0 ); /* Logical Max is the largest value that could be produced by a poll */ NEXT_BYTE(pucReport, HIDP_GLOBAL_LOG_MAX_2); NEXT_BYTE(pucReport, 255 ); NEXT_BYTE(pucReport, 0 ); NEXT_BYTE(pucReport, HIDP_MAIN_COLLECTION); NEXT_BYTE(pucReport, 0x01 ); NEXT_BYTE(pucReport, HIDP_GLOBAL_USAGE_PAGE_1); NEXT_BYTE(pucReport, HID_USAGE_PAGE_GENERIC); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 0x01); NEXT_BYTE(pucReport, HIDP_MAIN_COLLECTION); NEXT_BYTE(pucReport, 0x00 ); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_X); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_Y); if(numaxes > 2) { NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_Z); if(numaxes > 3) { NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_RZ); }; }; NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_SIZE); NEXT_BYTE(pucReport, 8); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_COUNT_1); NEXT_BYTE(pucReport, numaxes); NEXT_BYTE(pucReport, HIDP_MAIN_INPUT_1); NEXT_BYTE(pucReport, ITEM_VARIABLE); NEXT_BYTE(pucReport, HIDP_MAIN_ENDCOLLECTION); if(numaxes != 4) { NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 0); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_SIZE); NEXT_BYTE(pucReport, 8); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_COUNT_1); NEXT_BYTE(pucReport, 4-numaxes); NEXT_BYTE(pucReport, HIDP_MAIN_INPUT_1); NEXT_BYTE(pucReport, ITEM_PADDING); }; // Digital Buttons NEXT_BYTE(pucReport, HIDP_GLOBAL_USAGE_PAGE_1); NEXT_BYTE(pucReport, HID_USAGE_PAGE_BUTTON); // Boton NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_MIN_1); NEXT_BYTE(pucReport, 1 ); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_MAX_1); NEXT_BYTE(pucReport, 16 ); NEXT_BYTE(pucReport, HIDP_GLOBAL_LOG_MAX_1); NEXT_BYTE(pucReport, 1 ); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_SIZE); NEXT_BYTE(pucReport, 0x1); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_COUNT_1); NEXT_BYTE(pucReport, 16); NEXT_BYTE(pucReport, HIDP_MAIN_INPUT_1); NEXT_BYTE(pucReport, ITEM_VARIABLE); // Analog Buttons if(DeviceExtension->psx.Psx2) { NEXT_BYTE(pucReport, HIDP_GLOBAL_LOG_MAX_2); NEXT_BYTE(pucReport, 255); NEXT_BYTE(pucReport, 1); NEXT_BYTE(pucReport, HIDP_GLOBAL_USAGE_PAGE_1); NEXT_BYTE(pucReport, HID_USAGE_PAGE_GENERIC); NEXT_BYTE(pucReport, HIDP_MAIN_COLLECTION); NEXT_BYTE(pucReport, 0x00 ); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_RX); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_RY); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_DIAL); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, HID_USAGE_GENERIC_SLIDER); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_SIZE); NEXT_BYTE(pucReport, 16); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_COUNT_1); NEXT_BYTE(pucReport, 4); NEXT_BYTE(pucReport, HIDP_MAIN_INPUT_1); NEXT_BYTE(pucReport, ITEM_VARIABLE); NEXT_BYTE(pucReport, HIDP_MAIN_ENDCOLLECTION); } else { NEXT_BYTE(pucReport, HIDP_GLOBAL_USAGE_PAGE_1); NEXT_BYTE(pucReport, HID_USAGE_PAGE_GENERIC); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 0); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_SIZE); NEXT_BYTE(pucReport, 16); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_COUNT_1); NEXT_BYTE(pucReport, 4); NEXT_BYTE(pucReport, HIDP_MAIN_INPUT_1); NEXT_BYTE(pucReport, ITEM_PADDING); }; // FF NEXT_BYTE(pucReport, HIDP_GLOBAL_USAGE_PAGE_1); NEXT_BYTE(pucReport, HID_USAGE_PAGE_GENERIC); NEXT_BYTE(pucReport, HIDP_MAIN_COLLECTION); NEXT_BYTE(pucReport, 0x00 ); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 1); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 2); NEXT_BYTE(pucReport, HIDP_GLOBAL_LOG_MAX_2); NEXT_BYTE(pucReport, 255 ); NEXT_BYTE(pucReport, 0 ); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_SIZE); NEXT_BYTE(pucReport, 8); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_COUNT_1); NEXT_BYTE(pucReport, 2); NEXT_BYTE(pucReport, HIDP_MAIN_OUTPUT_1); NEXT_BYTE(pucReport, ITEM_VARIABLE); NEXT_BYTE(pucReport, HIDP_MAIN_ENDCOLLECTION); // Info NEXT_BYTE(pucReport, HIDP_GLOBAL_USAGE_PAGE_1); NEXT_BYTE(pucReport, HID_USAGE_PAGE_GENERIC); NEXT_BYTE(pucReport, HIDP_MAIN_COLLECTION); NEXT_BYTE(pucReport, 0x00 ); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 1); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 2); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 3); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 4); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 5); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 6); NEXT_BYTE(pucReport, HIDP_LOCAL_USAGE_1); NEXT_BYTE(pucReport, 7); NEXT_BYTE(pucReport, HIDP_GLOBAL_LOG_MAX_2); NEXT_BYTE(pucReport, 255 ); NEXT_BYTE(pucReport, 0 ); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_SIZE); NEXT_BYTE(pucReport, 8); NEXT_BYTE(pucReport, HIDP_GLOBAL_REPORT_COUNT_1); NEXT_BYTE(pucReport, 7); NEXT_BYTE(pucReport, HIDP_MAIN_FEATURE_1); NEXT_BYTE(pucReport, ITEM_VARIABLE); NEXT_BYTE(pucReport, HIDP_MAIN_ENDCOLLECTION); /* End of collection, We're done ! */ NEXT_BYTE(pucReport, HIDP_MAIN_ENDCOLLECTION); #undef NEXT_BYTE #undef NEXT_LONG if( pucReport - rgGameReport > MAXBYTES_GAME_REPORT) { ntStatus = STATUS_BUFFER_TOO_SMALL; *pCbReport = 0x0; RtlZeroMemory(rgGameReport, sizeof(rgGameReport)); } else { *pCbReport = (USHORT) (pucReport - rgGameReport); ntStatus = STATUS_SUCCESS; } HGM_DBGPRINT( FILE_HIDJOY | HGM_GEN_REPORT,\ ("HGM_GenerateReport: ReportSize=0x%x",\ *pCbReport) ); HGM_EXITPROC(FILE_HIDJOY | HGM_FEXIT_STATUSOK, "HGM_GenerateReport", ntStatus); return ( ntStatus ); } /* HGM_GenerateReport */