Ejemplo n.º 1
0
static void DrawControlGroupBox(wxDC &dc, ControlGroupBox *g)
{
    switch (g->control_group->type)
    {
    case GROUP_TYPE_TILT :
    case GROUP_TYPE_STICK :
    case GROUP_TYPE_CURSOR :
    {
        // this is starting to be a mess combining all these in one case

        double x = 0, y = 0, z = 0;

        switch (g->control_group->type)
        {
        case GROUP_TYPE_STICK :
            ((ControllerEmu::AnalogStick*)g->control_group)->GetState(&x, &y);
            break;
        case GROUP_TYPE_TILT :
            ((ControllerEmu::Tilt*)g->control_group)->GetState(&x, &y);
            break;
        case GROUP_TYPE_CURSOR :
            ((ControllerEmu::Cursor*)g->control_group)->GetState(&x, &y, &z);
            break;
        }

        // ir cursor forward movement
        if (GROUP_TYPE_CURSOR == g->control_group->type)
        {
            if (z)
            {
                dc.SetPen(*wxRED_PEN);
                dc.SetBrush(*wxRED_BRUSH);
            }
            else
            {
                dc.SetPen(*wxGREY_PEN);
                dc.SetBrush(*wxGREY_BRUSH);
            }
            dc.DrawRectangle(0, 31 - z*31, 64, 2);
        }

        // octagon for visual aid for diagonal adjustment
        dc.SetPen(*wxLIGHT_GREY_PEN);
        dc.SetBrush(*wxWHITE_BRUSH);
        if (GROUP_TYPE_STICK == g->control_group->type)
        {
            // outline and fill colors
            wxBrush LightGrayBrush("#dddddd");
            wxPen LightGrayPen("#bfbfbf");
            dc.SetBrush(LightGrayBrush);
            dc.SetPen(LightGrayPen);

            // polygon offset
            float max
            , diagonal
            , box = 64
                    , d_of = box / 256.0
                             , x_of = box / 2.0;

            if (g->control_group->name == "Main Stick")
            {
                max = (87.0f / 127.0f) * 100;
                diagonal = (55.0f / 127.0f) * 100.0;
            }
            else if (g->control_group->name == "C-Stick")
            {
                max = (74.0f / 127.0f) * 100;
                diagonal = (46.0f / 127.0f) * 100;
            }
            else
            {
                max = (82.0f / 127.0f) * 100;
                diagonal = (58.0f / 127.0f) * 100;
            }

            // polygon corners
            wxPoint Points[8];
            Points[0].x = (int)(0.0 * d_of + x_of);
            Points[0].y = (int)(max * d_of + x_of);
            Points[1].x = (int)(diagonal * d_of + x_of);
            Points[1].y = (int)(diagonal * d_of + x_of);
            Points[2].x = (int)(max * d_of + x_of);
            Points[2].y = (int)(0.0 * d_of + x_of);
            Points[3].x = (int)(diagonal * d_of + x_of);
            Points[3].y = (int)(-diagonal * d_of + x_of);
            Points[4].x = (int)(0.0 * d_of + x_of);
            Points[4].y = (int)(-max * d_of + x_of);
            Points[5].x = (int)(-diagonal * d_of + x_of);
            Points[5].y = (int)(-diagonal * d_of + x_of);
            Points[6].x = (int)(-max * d_of + x_of);
            Points[6].y = (int)(0.0 * d_of + x_of);
            Points[7].x = (int)(-diagonal * d_of + x_of);
            Points[7].y = (int)(diagonal * d_of + x_of);

            // draw polygon
            dc.DrawPolygon(8, Points);
        }
        else
        {
            dc.DrawRectangle(16, 16, 32, 32);
        }

        if (GROUP_TYPE_CURSOR != g->control_group->type)
        {
            // deadzone circle
            dc.SetBrush(*wxLIGHT_GREY_BRUSH);
            dc.DrawCircle(32, 32, g->control_group->settings[SETTING_DEADZONE]->value * 32);
        }

        // raw dot
        {
            float xx, yy;
            xx = g->control_group->controls[3]->control_ref->State();
            xx -= g->control_group->controls[2]->control_ref->State();
            yy = g->control_group->controls[1]->control_ref->State();
            yy -= g->control_group->controls[0]->control_ref->State();

            dc.SetPen(*wxGREY_PEN);
            dc.SetBrush(*wxGREY_BRUSH);
            DrawCoordinate(dc, xx, yy);
        }

        // adjusted dot
        if (x != 0 && y != 0)
        {
            dc.SetPen(*wxRED_PEN);
            dc.SetBrush(*wxRED_BRUSH);
            // XXX: The adjusted values flip the Y axis to be in the format
            // the Wii expects. Should this be in WiimoteEmu.cpp instead?
            DrawCoordinate(dc, x, -y);
        }
    }
    break;
    case GROUP_TYPE_FORCE :
    {
        double raw_dot[3];
        double adj_dot[3];
        const float deadzone = g->control_group->settings[0]->value;

        // adjusted
        ((ControllerEmu::Force*)g->control_group)->GetState(adj_dot);

        // raw
        for (unsigned int i=0; i<3; ++i)
        {
            raw_dot[i] = (g->control_group->controls[i*2 + 1]->control_ref->State() -
                          g->control_group->controls[i*2]->control_ref->State());
        }

        // deadzone rect for forward/backward visual
        dc.SetBrush(*wxLIGHT_GREY_BRUSH);
        dc.SetPen(*wxLIGHT_GREY_PEN);
        int deadzone_height = deadzone * VIS_BITMAP_SIZE;
        DrawCenteredRectangle(dc, 0, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE, deadzone_height);

#define LINE_HEIGHT 2
        int line_y;

        // raw forward/background line
        dc.SetPen(*wxGREY_PEN);
        dc.SetBrush(*wxGREY_BRUSH);
        line_y = VIS_COORD(raw_dot[2]);
        DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, line_y, VIS_BITMAP_SIZE, LINE_HEIGHT);

        // adjusted forward/background line
        if (adj_dot[2] != 0.0)
        {
            dc.SetPen(*wxRED_PEN);
            dc.SetBrush(*wxRED_BRUSH);
            line_y = VIS_COORD(adj_dot[2]);
            DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, line_y, VIS_BITMAP_SIZE, LINE_HEIGHT);
        }

#define DEADZONE_RECT_SIZE 32

        // empty deadzone square
        dc.SetBrush(*wxWHITE_BRUSH);
        dc.SetPen(*wxLIGHT_GREY_PEN);
        DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2, DEADZONE_RECT_SIZE, DEADZONE_RECT_SIZE);

        // deadzone square
        dc.SetBrush(*wxLIGHT_GREY_BRUSH);
        int dz_size = (deadzone * DEADZONE_RECT_SIZE);
        DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2, dz_size, dz_size);

        // raw dot
        dc.SetPen(*wxGREY_PEN);
        dc.SetBrush(*wxGREY_BRUSH);
        DrawCoordinate(dc, raw_dot[1], raw_dot[0]);

        // adjusted dot
        if (adj_dot[1] != 0 && adj_dot[0] != 0)
        {
            dc.SetPen(*wxRED_PEN);
            dc.SetBrush(*wxRED_BRUSH);
            DrawCoordinate(dc, adj_dot[1], adj_dot[0]);
        }

    }
    break;
    case GROUP_TYPE_BUTTONS :
    {
        const unsigned int button_count = ((unsigned int)g->control_group->controls.size());

        // draw the shit
        dc.SetPen(*wxGREY_PEN);

        unsigned int * const bitmasks = new unsigned int[ button_count ];
        for (unsigned int n = 0; n<button_count; ++n)
            bitmasks[n] = (1 << n);

        unsigned int buttons = 0;
        ((ControllerEmu::Buttons*)g->control_group)->GetState(&buttons, bitmasks);

        for (unsigned int n = 0; n<button_count; ++n)
        {
            if (buttons & bitmasks[n])
            {
                dc.SetBrush(*wxRED_BRUSH);
            }
            else
            {
                unsigned char amt = 255 - g->control_group->controls[n]->control_ref->State() * 128;
                dc.SetBrush(wxBrush(wxColour(amt, amt, amt)));
            }
            dc.DrawRectangle(n * 12, 0, 14, 12);

            // text
            const std::string name = g->control_group->controls[n]->name;
            // bit of hax so ZL, ZR show up as L, R
            dc.DrawText(StrToWxStr(std::string(1, (name[1] && name[1] < 'a') ? name[1] : name[0])), n*12 + 2, 1);
        }

        delete[] bitmasks;

    }
    break;
    case GROUP_TYPE_TRIGGERS :
    {
        const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size()));

        // draw the shit
        dc.SetPen(*wxGREY_PEN);
        ControlState deadzone =  g->control_group->settings[0]->value;

        double* const trigs = new double[trigger_count];
        ((ControllerEmu::Triggers*)g->control_group)->GetState(trigs);

        for (unsigned int n = 0; n < trigger_count; ++n)
        {
            ControlState trig_r = g->control_group->controls[n]->control_ref->State();

            // outline
            dc.SetPen(*wxGREY_PEN);
            dc.SetBrush(*wxWHITE_BRUSH);
            dc.DrawRectangle(0, n*12, 64, 14);

            // raw
            dc.SetBrush(*wxGREY_BRUSH);
            dc.DrawRectangle(0, n*12, trig_r*64, 14);

            // deadzone affected
            dc.SetBrush(*wxRED_BRUSH);
            dc.DrawRectangle(0, n*12, trigs[n]*64, 14);

            // text
            dc.DrawText(StrToWxStr(g->control_group->controls[n]->name), 3, n*12 + 1);
        }

        delete[] trigs;

        // deadzone box
        dc.SetPen(*wxLIGHT_GREY_PEN);
        dc.SetBrush(*wxTRANSPARENT_BRUSH);
        dc.DrawRectangle(0, 0, deadzone*64, trigger_count*14);

    }
    break;
    case GROUP_TYPE_MIXED_TRIGGERS :
    {
        const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size() / 2));

        // draw the shit
        dc.SetPen(*wxGREY_PEN);
        ControlState thresh = g->control_group->settings[0]->value;

        for (unsigned int n = 0; n < trigger_count; ++n)
        {
            dc.SetBrush(*wxRED_BRUSH);
            ControlState trig_d = g->control_group->controls[n]->control_ref->State();

            ControlState trig_a = trig_d > thresh ? 1
                                  : g->control_group->controls[n+trigger_count]->control_ref->State();

            dc.DrawRectangle(0, n*12, 64+20, 14);
            if (trig_d <= thresh)
                dc.SetBrush(*wxWHITE_BRUSH);
            dc.DrawRectangle(trig_a*64, n*12, 64+20, 14);
            dc.DrawRectangle(64, n*12, 32, 14);

            // text
            dc.DrawText(StrToWxStr(g->control_group->controls[n+trigger_count]->name), 3, n*12 + 1);
            dc.DrawText(StrToWxStr(std::string(1, g->control_group->controls[n]->name[0])), 64 + 3, n*12 + 1);
        }

        // threshold box
        dc.SetPen(*wxLIGHT_GREY_PEN);
        dc.SetBrush(*wxTRANSPARENT_BRUSH);
        dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);

    }
    break;
    case GROUP_TYPE_SLIDER:
    {
        const ControlState deadzone = g->control_group->settings[0]->value;

        ControlState state = g->control_group->controls[1]->control_ref->State() - g->control_group->controls[0]->control_ref->State();
        dc.SetPen(*wxGREY_PEN);
        dc.SetBrush(*wxGREY_BRUSH);
        dc.DrawRectangle(31 + state * 30, 0, 2, 14);

        double adj_state;
        ((ControllerEmu::Slider*)g->control_group)->GetState(&adj_state);
        if (state)
        {
            dc.SetPen(*wxRED_PEN);
            dc.SetBrush(*wxRED_BRUSH);
            dc.DrawRectangle(31 + adj_state * 30, 0, 2, 14);
        }

        // deadzone box
        dc.SetPen(*wxLIGHT_GREY_PEN);
        dc.SetBrush(*wxTRANSPARENT_BRUSH);
        dc.DrawRectangle(32 - deadzone * 32, 0, deadzone * 64, 14);
    }
    break;
    default:
        break;
    }
}
Ejemplo n.º 2
0
static void DrawCoordinate(wxDC &dc, double x, double y)
{
    int xc = VIS_COORD(x);
    int yc = VIS_COORD(y);
    DrawCenteredRectangle(dc, xc, yc, COORD_VIS_SIZE, COORD_VIS_SIZE);
}
Ejemplo n.º 3
0
static void DrawCoordinate(wxGraphicsContext* gc, ControlState x, ControlState y)
{
  double xc = VIS_COORD(x);
  double yc = VIS_COORD(y);
  DrawCenteredRectangle(gc, xc, yc, COORD_VIS_SIZE, COORD_VIS_SIZE);
}
Ejemplo n.º 4
0
static void DrawControlGroupBox(wxGraphicsContext* gc, ControlGroupBox* g)
{
  wxGraphicsMatrix null_matrix = gc->GetTransform();
  wxGraphicsMatrix scale_matrix = null_matrix;
  scale_matrix.Scale(g->m_scale, g->m_scale);

  gc->SetTransform(scale_matrix);

  switch (g->control_group->type)
  {
  case GROUP_TYPE_TILT:
  case GROUP_TYPE_STICK:
  case GROUP_TYPE_CURSOR:
  {
    // this is starting to be a mess combining all these in one case

    ControlState x = 0, y = 0, z = 0;

    switch (g->control_group->type)
    {
    case GROUP_TYPE_STICK:
      ((ControllerEmu::AnalogStick*)g->control_group)->GetState(&x, &y);
      break;
    case GROUP_TYPE_TILT:
      ((ControllerEmu::Tilt*)g->control_group)->GetState(&x, &y);
      break;
    case GROUP_TYPE_CURSOR:
      ((ControllerEmu::Cursor*)g->control_group)->GetState(&x, &y, &z);
      break;
    }

    // ir cursor forward movement
    if (GROUP_TYPE_CURSOR == g->control_group->type)
    {
      gc->SetBrush(z ? *wxRED_BRUSH : *wxGREY_BRUSH);
      wxGraphicsPath path = gc->CreatePath();
      path.AddRectangle(0, 31 - z * 31, 64, 2);
      gc->FillPath(path);
    }

    // input zone
    gc->SetPen(*wxLIGHT_GREY_PEN);
    if (GROUP_TYPE_STICK == g->control_group->type)
    {
      gc->SetBrush(wxColour(0xDDDDDD));  // Light Gray

      ShapePosition p;
      p.box = 64;
      p.offset = p.box / 2;
      p.range = 256;
      p.scale = p.box / p.range;
      p.dz = 15 * p.scale;
      bool octagon = false;

      if (g->control_group->name == "Main Stick")
      {
        p.max = 87 * p.scale;
        p.diag = 55 * p.scale;
      }
      else if (g->control_group->name == "C-Stick")
      {
        p.max = 74 * p.scale;
        p.diag = 46 * p.scale;
      }
      else
      {
        p.scale = 1;
        p.max = 32;
        octagon = true;
      }

      if (octagon)
        DrawOctagon(gc, p);
      else
        DrawDodecagon(gc, p);
    }
    else
    {
      gc->SetBrush(*wxWHITE_BRUSH);
      gc->DrawRectangle(16, 16, 32, 32);
    }

    if (GROUP_TYPE_CURSOR != g->control_group->type)
    {
      int deadzone_idx = g->control_group->type == GROUP_TYPE_STICK ? SETTING_DEADZONE : 0;
      wxGraphicsPath path = gc->CreatePath();
      path.AddCircle(VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2,
                     g->control_group->numeric_settings[deadzone_idx]->GetValue() *
                         VIS_BITMAP_SIZE / 2);
      gc->SetBrush(*wxLIGHT_GREY_BRUSH);
      gc->FillPath(path);
    }

    // raw dot
    ControlState xx, yy;
    xx = g->control_group->controls[3]->control_ref->State();
    xx -= g->control_group->controls[2]->control_ref->State();
    yy = g->control_group->controls[1]->control_ref->State();
    yy -= g->control_group->controls[0]->control_ref->State();

    gc->SetPen(*wxTRANSPARENT_PEN);
    gc->SetBrush(*wxGREY_BRUSH);
    DrawCoordinate(gc, xx, yy);

    // adjusted dot
    if (x != 0 || y != 0)
    {
      gc->SetBrush(*wxRED_BRUSH);
      // XXX: The adjusted values flip the Y axis to be in the format
      // the Wii expects. Should this be in WiimoteEmu.cpp instead?
      DrawCoordinate(gc, x, -y);
    }
  }
  break;

  case GROUP_TYPE_FORCE:
  {
    ControlState raw_dot[3];
    ControlState adj_dot[3];
    const ControlState deadzone = g->control_group->numeric_settings[0]->GetValue();

    // adjusted
    ((ControllerEmu::Force*)g->control_group)->GetState(adj_dot);

    // raw
    for (unsigned int i = 0; i < 3; ++i)
    {
      raw_dot[i] = (g->control_group->controls[i * 2 + 1]->control_ref->State() -
                    g->control_group->controls[i * 2]->control_ref->State());
    }

    // deadzone rect for forward/backward visual
    gc->SetPen(*wxTRANSPARENT_PEN);
    gc->SetBrush(*wxLIGHT_GREY_BRUSH);
    int deadzone_height = deadzone * VIS_BITMAP_SIZE;
    DrawCenteredRectangle(gc, 0, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE, deadzone_height);

#define LINE_HEIGHT 2
    int line_y;

    // raw forward/background line
    gc->SetBrush(*wxGREY_BRUSH);
    line_y = VIS_COORD(raw_dot[2]);
    DrawCenteredRectangle(gc, VIS_BITMAP_SIZE / 2, line_y, VIS_BITMAP_SIZE, LINE_HEIGHT);

    // adjusted forward/background line
    if (adj_dot[2] != 0.0)
    {
      gc->SetBrush(*wxRED_BRUSH);
      line_y = VIS_COORD(adj_dot[2]);
      DrawCenteredRectangle(gc, VIS_BITMAP_SIZE / 2, line_y, VIS_BITMAP_SIZE, LINE_HEIGHT);
    }

#define DEADZONE_RECT_SIZE 32

    // empty deadzone square
    gc->SetPen(*wxLIGHT_GREY_PEN);
    gc->SetBrush(*wxWHITE_BRUSH);
    DrawCenteredRectangle(gc, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2, DEADZONE_RECT_SIZE,
                          DEADZONE_RECT_SIZE);

    // deadzone square
    gc->SetPen(*wxTRANSPARENT_PEN);
    gc->SetBrush(*wxLIGHT_GREY_BRUSH);
    int dz_size = (deadzone * DEADZONE_RECT_SIZE);
    DrawCenteredRectangle(gc, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2, dz_size, dz_size);

    // raw dot
    gc->SetBrush(*wxGREY_BRUSH);
    DrawCoordinate(gc, raw_dot[1], raw_dot[0]);

    // adjusted dot
    if (adj_dot[1] != 0 && adj_dot[0] != 0)
    {
      gc->SetBrush(*wxRED_BRUSH);
      DrawCoordinate(gc, adj_dot[1], adj_dot[0]);
    }
  }
  break;

  case GROUP_TYPE_BUTTONS:
  {
    const unsigned int button_count = static_cast<unsigned int>(g->control_group->controls.size());
    std::vector<unsigned int> bitmasks(button_count);

    // draw the shit
    gc->SetPen(*wxGREY_PEN);

    for (unsigned int n = 0; n < button_count; ++n)
      bitmasks[n] = (1 << n);

    unsigned int buttons = 0;
    ((ControllerEmu::Buttons*)g->control_group)->GetState(&buttons, bitmasks.data());

    // Draw buttons in rows of 8
    for (unsigned int row = 0; row < ceil((float)button_count / 8.0f); row++)
    {
      unsigned int buttons_to_draw = 8;
      if ((button_count - row * 8) <= 8)
        buttons_to_draw = button_count - row * 8;

      for (unsigned int n = 0; n < buttons_to_draw; ++n)
      {
        DrawButton(bitmasks, buttons, n, gc, g, row, null_matrix);
      }
    }
  }
  break;

  case GROUP_TYPE_TRIGGERS:
  {
    const unsigned int trigger_count = static_cast<unsigned int>(g->control_group->controls.size());
    std::vector<ControlState> trigs(trigger_count);

    // draw the shit
    gc->SetPen(*wxGREY_PEN);

    ControlState deadzone = g->control_group->numeric_settings[0]->GetValue();
    ((ControllerEmu::Triggers*)g->control_group)->GetState(trigs.data());

    for (unsigned int n = 0; n < trigger_count; ++n)
    {
      ControlState trig_r = g->control_group->controls[n]->control_ref->State();

      // outline
      gc->SetBrush(*wxWHITE_BRUSH);
      gc->DrawRectangle(0, n * 12, 64, 14);

      // raw
      gc->SetBrush(*wxGREY_BRUSH);
      gc->DrawRectangle(0, n * 12, trig_r * 64, 14);

      // deadzone affected
      gc->SetBrush(*wxRED_BRUSH);
      gc->DrawRectangle(0, n * 12, trigs[n] * 64, 14);

      // text
      // We don't want the text to be scaled/zoomed
      gc->SetTransform(null_matrix);
      gc->DrawText(StrToWxStr(g->control_group->controls[n]->name), 3 * g->m_scale,
                   (n * 12 + 1) * g->m_scale);
      gc->SetTransform(scale_matrix);
    }

    // deadzone box
    gc->SetPen(*wxLIGHT_GREY_PEN);
    gc->SetBrush(*wxTRANSPARENT_BRUSH);
    gc->DrawRectangle(0, 0, deadzone * 64, trigger_count * 14);
  }
  break;

  case GROUP_TYPE_MIXED_TRIGGERS:
  {
    const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size() / 2));

    // draw the shit
    gc->SetPen(*wxGREY_PEN);
    ControlState thresh = g->control_group->numeric_settings[0]->GetValue();

    for (unsigned int n = 0; n < trigger_count; ++n)
    {
      gc->SetBrush(*wxRED_BRUSH);

      ControlState trig_d = g->control_group->controls[n]->control_ref->State();

      ControlState trig_a =
          trig_d > thresh ? 1 : g->control_group->controls[n + trigger_count]->control_ref->State();

      gc->DrawRectangle(0, n * 12, 64 + 20, 14);
      if (trig_d <= thresh)
        gc->SetBrush(*wxWHITE_BRUSH);
      gc->DrawRectangle(trig_a * 64, n * 12, 64 + 20, 14);
      gc->DrawRectangle(64, n * 12, 32, 14);

      // text
      // We don't want the text to be scaled/zoomed
      gc->SetTransform(null_matrix);
      gc->DrawText(StrToWxStr(g->control_group->controls[n + trigger_count]->name), 3 * g->m_scale,
                   (n * 12 + 1) * g->m_scale);
      gc->DrawText(StrToWxStr(std::string(1, g->control_group->controls[n]->name[0])),
                   (64 + 3) * g->m_scale, (n * 12 + 1) * g->m_scale);
      gc->SetTransform(scale_matrix);
    }

    // threshold box
    gc->SetPen(*wxLIGHT_GREY_PEN);
    gc->SetBrush(*wxTRANSPARENT_BRUSH);
    gc->DrawRectangle(thresh * 64, 0, 128, trigger_count * 14);
  }
  break;

  case GROUP_TYPE_SLIDER:
  {
    const ControlState deadzone = g->control_group->numeric_settings[0]->GetValue();

    ControlState state = g->control_group->controls[1]->control_ref->State() -
                         g->control_group->controls[0]->control_ref->State();
    gc->SetPen(*wxTRANSPARENT_PEN);
    gc->SetBrush(*wxGREY_BRUSH);
    gc->DrawRectangle(31 + state * 30, 0, 2, 14);

    ControlState adj_state;
    ((ControllerEmu::Slider*)g->control_group)->GetState(&adj_state);
    if (state)
    {
      gc->SetBrush(*wxRED_BRUSH);
      gc->DrawRectangle(31 + adj_state * 30, 0, 2, 14);
    }

    // deadzone box
    gc->SetPen(*wxLIGHT_GREY_PEN);
    gc->SetBrush(*wxTRANSPARENT_BRUSH);
    gc->DrawRectangle(32 - deadzone * 32, 0, deadzone * 64, 14);
  }
  break;

  default:
    break;
  }
  gc->SetTransform(null_matrix);
}
Ejemplo n.º 5
0
static void DrawControlGroupBox(wxDC &dc, ControlGroupBox *g)
{
	switch (g->control_group->type)
	{
	case GROUP_TYPE_TILT :
	case GROUP_TYPE_STICK :
	case GROUP_TYPE_CURSOR :
	{
		// this is starting to be a mess combining all these in one case

		ControlState x = 0, y = 0, z = 0;

		switch (g->control_group->type)
		{
		case GROUP_TYPE_STICK :
			((ControllerEmu::AnalogStick*)g->control_group)->GetState(&x, &y);
			break;
		case GROUP_TYPE_TILT :
			((ControllerEmu::Tilt*)g->control_group)->GetState(&x, &y);
			break;
		case GROUP_TYPE_CURSOR :
			((ControllerEmu::Cursor*)g->control_group)->GetState(&x, &y, &z);
			break;
		}

		// ir cursor forward movement
		if (GROUP_TYPE_CURSOR == g->control_group->type)
		{
			if (z)
			{
				dc.SetPen(*wxRED_PEN);
				dc.SetBrush(*wxRED_BRUSH);
			}
			else
			{
				dc.SetPen(*wxGREY_PEN);
				dc.SetBrush(*wxGREY_BRUSH);
			}
			dc.DrawRectangle(0, 31 - z*31, 64, 2);
		}

		// input zone
		dc.SetPen(*wxLIGHT_GREY_PEN);
		dc.SetBrush(*wxWHITE_BRUSH);
		if (GROUP_TYPE_STICK == g->control_group->type)
		{
			// outline and fill colors
			wxBrush LightGrayBrush("#dddddd");
			wxPen LightGrayPen("#bfbfbf");
			dc.SetBrush(LightGrayBrush);
			dc.SetPen(LightGrayPen);

			ShapePosition p;
			p.box = 64;
			p.offset = p.box / 2;
			p.range = 256;
			p.scale = p.box / p.range;
			p.dz = 15 * p.scale;
			bool octagon = false;

			if (g->control_group->name == "Main Stick")
			{
				p.max = 87 * p.scale;
				p.diag = 55 * p.scale;
			}
			else if (g->control_group->name == "C-Stick")
			{
				p.max = 74 * p.scale;
				p.diag = 46 * p.scale;
			}
			else
			{
				p.scale = 1;
				p.max = 32;
				octagon = true;
			}

			if (octagon)
				DrawOctagon(&dc, p);
			else
				DrawDodecagon(&dc, p);
		}
		else
		{
			dc.DrawRectangle(16, 16, 32, 32);
		}

		if (GROUP_TYPE_CURSOR != g->control_group->type)
		{
			// deadzone circle
			dc.SetBrush(*wxLIGHT_GREY_BRUSH);
			dc.DrawCircle(32, 32, g->control_group->settings[SETTING_DEADZONE]->value * 32);
		}

		// raw dot
		{
		ControlState xx, yy;
		xx = g->control_group->controls[3]->control_ref->State();
		xx -= g->control_group->controls[2]->control_ref->State();
		yy = g->control_group->controls[1]->control_ref->State();
		yy -= g->control_group->controls[0]->control_ref->State();

		dc.SetPen(*wxGREY_PEN);
		dc.SetBrush(*wxGREY_BRUSH);
		DrawCoordinate(dc, xx, yy);
		}

		// adjusted dot
		if (x != 0 || y != 0)
		{
			dc.SetPen(*wxRED_PEN);
			dc.SetBrush(*wxRED_BRUSH);
			// XXX: The adjusted values flip the Y axis to be in the format
			// the Wii expects. Should this be in WiimoteEmu.cpp instead?
			DrawCoordinate(dc, x, -y);
		}
	}
	break;
	case GROUP_TYPE_FORCE :
	{
		ControlState raw_dot[3];
		ControlState adj_dot[3];
		const ControlState deadzone = g->control_group->settings[0]->value;

		// adjusted
		((ControllerEmu::Force*)g->control_group)->GetState(adj_dot);

		// raw
		for (unsigned int i=0; i<3; ++i)
		{
			raw_dot[i] = (g->control_group->controls[i*2 + 1]->control_ref->State() -
				      g->control_group->controls[i*2]->control_ref->State());
		}

		// deadzone rect for forward/backward visual
		dc.SetBrush(*wxLIGHT_GREY_BRUSH);
		dc.SetPen(*wxLIGHT_GREY_PEN);
		int deadzone_height = deadzone * VIS_BITMAP_SIZE;
		DrawCenteredRectangle(dc, 0, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE, deadzone_height);

#define LINE_HEIGHT 2
		int line_y;

		// raw forward/background line
		dc.SetPen(*wxGREY_PEN);
		dc.SetBrush(*wxGREY_BRUSH);
		line_y = VIS_COORD(raw_dot[2]);
		DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, line_y, VIS_BITMAP_SIZE, LINE_HEIGHT);

		// adjusted forward/background line
		if (adj_dot[2] != 0.0)
		{
			dc.SetPen(*wxRED_PEN);
			dc.SetBrush(*wxRED_BRUSH);
			line_y = VIS_COORD(adj_dot[2]);
			DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, line_y, VIS_BITMAP_SIZE, LINE_HEIGHT);
		}

#define DEADZONE_RECT_SIZE 32

		// empty deadzone square
		dc.SetBrush(*wxWHITE_BRUSH);
		dc.SetPen(*wxLIGHT_GREY_PEN);
		DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2, DEADZONE_RECT_SIZE, DEADZONE_RECT_SIZE);

		// deadzone square
		dc.SetBrush(*wxLIGHT_GREY_BRUSH);
		int dz_size = (deadzone * DEADZONE_RECT_SIZE);
		DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2, dz_size, dz_size);

		// raw dot
		dc.SetPen(*wxGREY_PEN);
		dc.SetBrush(*wxGREY_BRUSH);
		DrawCoordinate(dc, raw_dot[1], raw_dot[0]);

		// adjusted dot
		if (adj_dot[1] != 0 && adj_dot[0] != 0)
		{
			dc.SetPen(*wxRED_PEN);
			dc.SetBrush(*wxRED_BRUSH);
			DrawCoordinate(dc, adj_dot[1], adj_dot[0]);
		}

	}
	break;
	case GROUP_TYPE_BUTTONS :
	{
		unsigned int button_count = ((unsigned int)g->control_group->controls.size());

		// draw the shit
		dc.SetPen(*wxGREY_PEN);

		unsigned int* const bitmasks = new unsigned int[button_count];
		for (unsigned int n = 0; n<button_count; ++n)
			bitmasks[n] = (1 << n);

		unsigned int buttons = 0;
		((ControllerEmu::Buttons*)g->control_group)->GetState(&buttons, bitmasks);

		// Draw buttons in rows of 8
		for (unsigned int row = 0; row < ceil((float)button_count / 8.0f); row++)
		{
			unsigned int buttons_to_draw = 8;
			if ((button_count - row * 8) <= 8)
				buttons_to_draw = button_count - row * 8;

			for (unsigned int n = 0; n < buttons_to_draw; ++n)
			{
				DrawButton(bitmasks, buttons, n, dc, g, row);
			}
		}

		delete[] bitmasks;

	}
	break;
	case GROUP_TYPE_TRIGGERS :
	{
		const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size()));

		// draw the shit
		dc.SetPen(*wxGREY_PEN);
		ControlState deadzone =  g->control_group->settings[0]->value;

		ControlState* const trigs = new ControlState[trigger_count];
		((ControllerEmu::Triggers*)g->control_group)->GetState(trigs);

		for (unsigned int n = 0; n < trigger_count; ++n)
		{
			ControlState trig_r = g->control_group->controls[n]->control_ref->State();

			// outline
			dc.SetPen(*wxGREY_PEN);
			dc.SetBrush(*wxWHITE_BRUSH);
			dc.DrawRectangle(0, n*12, 64, 14);

			// raw
			dc.SetBrush(*wxGREY_BRUSH);
			dc.DrawRectangle(0, n*12, trig_r*64, 14);

			// deadzone affected
			dc.SetBrush(*wxRED_BRUSH);
			dc.DrawRectangle(0, n*12, trigs[n]*64, 14);

			// text
			dc.DrawText(StrToWxStr(g->control_group->controls[n]->name), 3, n*12 + 1);
		}

		delete[] trigs;

		// deadzone box
		dc.SetPen(*wxLIGHT_GREY_PEN);
		dc.SetBrush(*wxTRANSPARENT_BRUSH);
		dc.DrawRectangle(0, 0, deadzone*64, trigger_count*14);

	}
	break;
	case GROUP_TYPE_MIXED_TRIGGERS :
	{
		const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size() / 2));

		// draw the shit
		dc.SetPen(*wxGREY_PEN);
		ControlState thresh = g->control_group->settings[0]->value;

		for (unsigned int n = 0; n < trigger_count; ++n)
		{
			dc.SetBrush(*wxRED_BRUSH);
			ControlState trig_d = g->control_group->controls[n]->control_ref->State();

			ControlState trig_a = trig_d > thresh ? 1
				: g->control_group->controls[n+trigger_count]->control_ref->State();

			dc.DrawRectangle(0, n*12, 64+20, 14);
			if (trig_d <= thresh)
				dc.SetBrush(*wxWHITE_BRUSH);
			dc.DrawRectangle(trig_a*64, n*12, 64+20, 14);
			dc.DrawRectangle(64, n*12, 32, 14);

			// text
			dc.DrawText(StrToWxStr(g->control_group->controls[n+trigger_count]->name), 3, n*12 + 1);
			dc.DrawText(StrToWxStr(std::string(1, g->control_group->controls[n]->name[0])), 64 + 3, n*12 + 1);
		}

		// threshold box
		dc.SetPen(*wxLIGHT_GREY_PEN);
		dc.SetBrush(*wxTRANSPARENT_BRUSH);
		dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);

	}
	break;
	case GROUP_TYPE_SLIDER:
	{
		const ControlState deadzone = g->control_group->settings[0]->value;

		ControlState state = g->control_group->controls[1]->control_ref->State() - g->control_group->controls[0]->control_ref->State();
		dc.SetPen(*wxGREY_PEN);
		dc.SetBrush(*wxGREY_BRUSH);
		dc.DrawRectangle(31 + state * 30, 0, 2, 14);

		ControlState adj_state;
		((ControllerEmu::Slider*)g->control_group)->GetState(&adj_state);
		if (state)
		{
			dc.SetPen(*wxRED_PEN);
			dc.SetBrush(*wxRED_BRUSH);
			dc.DrawRectangle(31 + adj_state * 30, 0, 2, 14);
		}

		// deadzone box
		dc.SetPen(*wxLIGHT_GREY_PEN);
		dc.SetBrush(*wxTRANSPARENT_BRUSH);
		dc.DrawRectangle(32 - deadzone * 32, 0, deadzone * 64, 14);
	}
	break;
	default:
	break;
	}
}