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;
}
Exemple #4
0
/*****************************************************************************
 *
 *  @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 */