Example #1
0
void GameSurface::OnMouseMoveEvent(const SDL_Event& event)
{
	auto& e = reinterpret_cast<const SDL_MouseMotionEvent&>(event);
	Position position;
	position.X = e.x;
	position.Y = e.y;
	if (e.state == SDL_BUTTON_LEFT)
	{
		auto gemPosition = CalculateGemPosition(m_selectedGem);
		if (m_selectedGem != k_noGem 
			&& (SDL_abs(gemPosition.X - position.X) > GemSurface::WIDTH / 2
			|| SDL_abs(gemPosition.Y - position.Y) > GemSurface::HEIGHT / 2))
		{
			gemPosition.X = position.X - gemPosition.X;
			gemPosition.Y = position.Y - gemPosition.Y;
			m_gems[m_selectedGem].SetOffset(gemPosition);
			m_gems[m_selectedGem].SetDragging(true);
		}
	}
	for (auto& child : m_gems)
	{
		child.SetHover(false);
		if (child.Contains(position))
		{
			child.SetHover(true);
		}
	}
}
Example #2
0
bool GameSurface::AreContiguous(std::uint8_t first, std::uint8_t second) const
{
	if (first == second)
		return false;
	if (first / COLUMNS == second / COLUMNS)
		return first + 1 == second || first - 1 == second;
	else
		return SDL_abs(first - second) == COLUMNS;
}
Example #3
0
int
SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
{
    int posted;

    /* Make sure we're not getting garbage or duplicate events */
    if (axis >= joystick->naxes) {
        return 0;
    }
    if (!joystick->axes[axis].has_initial_value) {
        joystick->axes[axis].initial_value = value;
        joystick->axes[axis].value = value;
        joystick->axes[axis].zero = value;
        joystick->axes[axis].has_initial_value = SDL_TRUE;
    }
    if (value == joystick->axes[axis].value) {
        return 0;
    }
    if (!joystick->axes[axis].sent_initial_value) {
        /* Make sure we don't send motion until there's real activity on this axis */
        const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80;  /* ShanWan PS3 controller needed 96 */
        if (SDL_abs(value - joystick->axes[axis].value) <= MAX_ALLOWED_JITTER) {
            return 0;
        }
        joystick->axes[axis].sent_initial_value = SDL_TRUE;
        joystick->axes[axis].value = value; /* Just so we pass the check above */
        SDL_PrivateJoystickAxis(joystick, axis, joystick->axes[axis].initial_value);
    }

    /* We ignore events if we don't have keyboard focus, except for centering
     * events.
     */
    if (SDL_PrivateJoystickShouldIgnoreEvent()) {
        if ((value > joystick->axes[axis].zero && value >= joystick->axes[axis].value) ||
            (value < joystick->axes[axis].zero && value <= joystick->axes[axis].value)) {
            return 0;
        }
    }

    /* Update internal joystick state */
    joystick->axes[axis].value = value;

    /* Post the event, if desired */
    posted = 0;
#if !SDL_EVENTS_DISABLED
    if (SDL_GetEventState(SDL_JOYAXISMOTION) == SDL_ENABLE) {
        SDL_Event event;
        event.type = SDL_JOYAXISMOTION;
        event.jaxis.which = joystick->instance_id;
        event.jaxis.axis = axis;
        event.jaxis.value = value;
        posted = SDL_PushEvent(&event) == 1;
    }
#endif /* !SDL_EVENTS_DISABLED */
    return (posted);
}
Example #4
0
/*	eloParsePacket
*/
int
eloParsePacket(unsigned char *mousebuf, int *dx, int *dy, int *button_state)
{
    static int elo_button = 0;
    static int last_x = 0;
    static int last_y = 0;
    int x, y;

    /* Check if we have a touch packet */
    if (mousebuf[1] != ELO_TOUCH_BYTE) {
        return 0;
    }

    x = ((mousebuf[4] << 8) | mousebuf[3]);
    y = ((mousebuf[6] << 8) | mousebuf[5]);

    if ((SDL_abs(x - last_x) > ELO_SNAP_SIZE)
        || (SDL_abs(y - last_y) > ELO_SNAP_SIZE)) {
        *dx = ((mousebuf[4] << 8) | mousebuf[3]);
        *dy = ((mousebuf[6] << 8) | mousebuf[5]);
    } else {
        *dx = last_x;
        *dy = last_y;
    }

    last_x = *dx;
    last_y = *dy;

    if ((mousebuf[2] & 0x07) == ELO_BTN_PRESS) {
        elo_button = 1;
    }
    if ((mousebuf[2] & 0x07) == ELO_BTN_RELEASE) {
        elo_button = 0;
    }

    *button_state = elo_button;
    return 1;
}
void C_GamepadManager::RepairAppositeStickComponent( int* pstickComponent )
{
    // スティックが遊び値以内の場合
    if ( SDL_abs( ( *pstickComponent ) ) < s_STICK_DEAD_ZONE )
    {
        ( *pstickComponent ) = 0;
    }
    else
    {
        // スティックが最大値を超過だった場合
        if ( ( *pstickComponent ) > s_STICK_PUSH_MAX )
        {
            ( *pstickComponent ) = s_STICK_PUSH_MAX;
        }
        // スティックが最小値未満だった場合
        else if ( ( *pstickComponent ) < s_STICK_PUSH_MINI )
        {
            ( *pstickComponent ) = s_STICK_PUSH_MINI;
        }
    }
}
Example #6
0
/*
 * Creates the FFEFFECT from a SDL_HapticEffect.
 */
static int
SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src)
{
    int i;
    FFCONSTANTFORCE *constant = NULL;
    FFPERIODIC *periodic = NULL;
    FFCONDITION *condition = NULL;     /* Actually an array of conditions - one per axis. */
    FFRAMPFORCE *ramp = NULL;
    FFCUSTOMFORCE *custom = NULL;
    FFENVELOPE *envelope = NULL;
    SDL_HapticConstant *hap_constant = NULL;
    SDL_HapticPeriodic *hap_periodic = NULL;
    SDL_HapticCondition *hap_condition = NULL;
    SDL_HapticRamp *hap_ramp = NULL;
    SDL_HapticCustom *hap_custom = NULL;
    DWORD *axes = NULL;

    /* Set global stuff. */
    SDL_memset(dest, 0, sizeof(FFEFFECT));
    dest->dwSize = sizeof(FFEFFECT);    /* Set the structure size. */
    dest->dwSamplePeriod = 0;   /* Not used by us. */
    dest->dwGain = 10000;       /* Gain is set globally, not locally. */
    dest->dwFlags = FFEFF_OBJECTOFFSETS;        /* Seems obligatory. */

    /* Envelope. */
    envelope = SDL_malloc(sizeof(FFENVELOPE));
    if (envelope == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(envelope, 0, sizeof(FFENVELOPE));
    dest->lpEnvelope = envelope;
    envelope->dwSize = sizeof(FFENVELOPE);      /* Always should be this. */

    /* Axes. */
    dest->cAxes = haptic->naxes;
    if (dest->cAxes > 0) {
        axes = SDL_malloc(sizeof(DWORD) * dest->cAxes);
        if (axes == NULL) {
            return SDL_OutOfMemory();
        }
        axes[0] = haptic->hwdata->axes[0];      /* Always at least one axis. */
        if (dest->cAxes > 1) {
            axes[1] = haptic->hwdata->axes[1];
        }
        if (dest->cAxes > 2) {
            axes[2] = haptic->hwdata->axes[2];
        }
        dest->rgdwAxes = axes;
    }


    /* The big type handling switch, even bigger then Linux's version. */
    switch (src->type) {
    case SDL_HAPTIC_CONSTANT:
        hap_constant = &src->constant;
        constant = SDL_malloc(sizeof(FFCONSTANTFORCE));
        if (constant == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE));

        /* Specifics */
        constant->lMagnitude = CONVERT(hap_constant->level);
        dest->cbTypeSpecificParams = sizeof(FFCONSTANTFORCE);
        dest->lpvTypeSpecificParams = constant;

        /* Generics */
        dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_constant->button);
        dest->dwTriggerRepeatInterval = hap_constant->interval;
        dest->dwStartDelay = hap_constant->delay * 1000;        /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes)
            < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_constant->attack_length == 0)
            && (hap_constant->fade_length == 0)) {
            SDL_free(envelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_constant->attack_level);
            envelope->dwAttackTime = hap_constant->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_constant->fade_level);
            envelope->dwFadeTime = hap_constant->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_SINE:
    /* !!! FIXME: put this back when we have more bits in 2.1 */
    /* case SDL_HAPTIC_SQUARE: */
    case SDL_HAPTIC_TRIANGLE:
    case SDL_HAPTIC_SAWTOOTHUP:
    case SDL_HAPTIC_SAWTOOTHDOWN:
        hap_periodic = &src->periodic;
        periodic = SDL_malloc(sizeof(FFPERIODIC));
        if (periodic == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(periodic, 0, sizeof(FFPERIODIC));

        /* Specifics */
        periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude));
        periodic->lOffset = CONVERT(hap_periodic->offset);
        periodic->dwPhase = 
                (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000;
        periodic->dwPeriod = hap_periodic->period * 1000;
        dest->cbTypeSpecificParams = sizeof(FFPERIODIC);
        dest->lpvTypeSpecificParams = periodic;

        /* Generics */
        dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_periodic->button);
        dest->dwTriggerRepeatInterval = hap_periodic->interval;
        dest->dwStartDelay = hap_periodic->delay * 1000;        /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes)
            < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_periodic->attack_length == 0)
            && (hap_periodic->fade_length == 0)) {
            SDL_free(envelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_periodic->attack_level);
            envelope->dwAttackTime = hap_periodic->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_periodic->fade_level);
            envelope->dwFadeTime = hap_periodic->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_SPRING:
    case SDL_HAPTIC_DAMPER:
    case SDL_HAPTIC_INERTIA:
    case SDL_HAPTIC_FRICTION:
        hap_condition = &src->condition;
        if (dest->cAxes > 0) {
            condition = SDL_malloc(sizeof(FFCONDITION) * dest->cAxes);
            if (condition == NULL) {
                return SDL_OutOfMemory();
            }
            SDL_memset(condition, 0, sizeof(FFCONDITION));

            /* Specifics */
            for (i = 0; i < dest->cAxes; i++) {
                condition[i].lOffset = CONVERT(hap_condition->center[i]);
                condition[i].lPositiveCoefficient =
                    CONVERT(hap_condition->right_coeff[i]);
                condition[i].lNegativeCoefficient =
                    CONVERT(hap_condition->left_coeff[i]);
                condition[i].dwPositiveSaturation =
                    CCONVERT(hap_condition->right_sat[i] / 2);
                condition[i].dwNegativeSaturation =
                    CCONVERT(hap_condition->left_sat[i] / 2);
                condition[i].lDeadBand = CCONVERT(hap_condition->deadband[i] / 2);
            }
        }

        dest->cbTypeSpecificParams = sizeof(FFCONDITION) * dest->cAxes;
        dest->lpvTypeSpecificParams = condition;

        /* Generics */
        dest->dwDuration = hap_condition->length * 1000;        /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_condition->button);
        dest->dwTriggerRepeatInterval = hap_condition->interval;
        dest->dwStartDelay = hap_condition->delay * 1000;       /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes)
            < 0) {
            return -1;
        }

        /* Envelope - Not actually supported by most CONDITION implementations. */
        SDL_free(dest->lpEnvelope);
        dest->lpEnvelope = NULL;

        break;

    case SDL_HAPTIC_RAMP:
        hap_ramp = &src->ramp;
        ramp = SDL_malloc(sizeof(FFRAMPFORCE));
        if (ramp == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(ramp, 0, sizeof(FFRAMPFORCE));

        /* Specifics */
        ramp->lStart = CONVERT(hap_ramp->start);
        ramp->lEnd = CONVERT(hap_ramp->end);
        dest->cbTypeSpecificParams = sizeof(FFRAMPFORCE);
        dest->lpvTypeSpecificParams = ramp;

        /* Generics */
        dest->dwDuration = hap_ramp->length * 1000;     /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_ramp->button);
        dest->dwTriggerRepeatInterval = hap_ramp->interval;
        dest->dwStartDelay = hap_ramp->delay * 1000;    /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_ramp->attack_length == 0) && (hap_ramp->fade_length == 0)) {
            SDL_free(envelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_ramp->attack_level);
            envelope->dwAttackTime = hap_ramp->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_ramp->fade_level);
            envelope->dwFadeTime = hap_ramp->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_CUSTOM:
        hap_custom = &src->custom;
        custom = SDL_malloc(sizeof(FFCUSTOMFORCE));
        if (custom == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(custom, 0, sizeof(FFCUSTOMFORCE));

        /* Specifics */
        custom->cChannels = hap_custom->channels;
        custom->dwSamplePeriod = hap_custom->period * 1000;
        custom->cSamples = hap_custom->samples;
        custom->rglForceData =
            SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels);
        for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) {      /* Copy data. */
            custom->rglForceData[i] = CCONVERT(hap_custom->data[i]);
        }
        dest->cbTypeSpecificParams = sizeof(FFCUSTOMFORCE);
        dest->lpvTypeSpecificParams = custom;

        /* Generics */
        dest->dwDuration = hap_custom->length * 1000;   /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_custom->button);
        dest->dwTriggerRepeatInterval = hap_custom->interval;
        dest->dwStartDelay = hap_custom->delay * 1000;  /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) <
            0) {
            return -1;
        }

        /* Envelope */
        if ((hap_custom->attack_length == 0)
            && (hap_custom->fade_length == 0)) {
            SDL_free(envelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_custom->attack_level);
            envelope->dwAttackTime = hap_custom->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_custom->fade_level);
            envelope->dwFadeTime = hap_custom->fade_length * 1000;
        }

        break;


    default:
        return SDL_SetError("Haptic: Unknown effect type.");
    }

    return 0;
}
Example #7
0
int
SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
{
    SDL_Mouse *mouse = SDL_GetMouse();
    int posted;
    Uint32 type;
    Uint32 buttonstate = mouse->buttonstate;
    SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
    Uint8 click_count;

    /* Figure out which event to perform */
    switch (state) {
    case SDL_PRESSED:
        type = SDL_MOUSEBUTTONDOWN;
        buttonstate |= SDL_BUTTON(button);
        break;
    case SDL_RELEASED:
        type = SDL_MOUSEBUTTONUP;
        buttonstate &= ~SDL_BUTTON(button);
        break;
    default:
        /* Invalid state -- bail */
        return 0;
    }

    /* We do this after calculating buttonstate so button presses gain focus */
    if (window && state == SDL_PRESSED) {
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
    }

    if (buttonstate == mouse->buttonstate) {
        /* Ignore this event, no state change */
        return 0;
    }
    mouse->buttonstate = buttonstate;

    if (clickstate) {
        if (state == SDL_PRESSED) {
            Uint32 now = SDL_GetTicks();

            if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) ||
                SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius ||
                SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) {
                clickstate->click_count = 0;
            }
            clickstate->last_timestamp = now;
            clickstate->last_x = mouse->x;
            clickstate->last_y = mouse->y;
            if (clickstate->click_count < 255) {
                ++clickstate->click_count;
            }
        }
        click_count = clickstate->click_count;
    } else {
        click_count = 1;
    }

    /* Post the event, if desired */
    posted = 0;
    if (SDL_GetEventState(type) == SDL_ENABLE) {
        SDL_Event event;
        event.type = type;
        event.button.windowID = mouse->focus ? mouse->focus->id : 0;
        event.button.which = mouseID;
        event.button.state = state;
        event.button.button = button;
        event.button.clicks = click_count;
        event.button.x = mouse->x;
        event.button.y = mouse->y;
        posted = (SDL_PushEvent(&event) > 0);
    }

    /* We do this after dispatching event so button releases can lose focus */
    if (window && state == SDL_RELEASED) {
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
    }

    return posted;
}
Example #8
0
static int
SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
{
    SDL_Mouse *mouse = SDL_GetMouse();
    int posted;
    Uint32 type;
    Uint32 buttonstate = mouse->buttonstate;

    /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
    if (mouse->mouse_touch_events) {
        if (mouseID != SDL_TOUCH_MOUSEID && button == SDL_BUTTON_LEFT) {
            if (state == SDL_PRESSED) {
                track_mouse_down = SDL_TRUE;
            } else {
                track_mouse_down = SDL_FALSE;
            }
            if (window) {
                float fx = (float)mouse->x / (float)window->w;
                float fy = (float)mouse->y / (float)window->h;
                SDL_SendTouch(SDL_MOUSE_TOUCHID, 0, track_mouse_down, fx, fy, 1.0f);
            }
        }
    }

    /* Figure out which event to perform */
    switch (state) {
    case SDL_PRESSED:
        type = SDL_MOUSEBUTTONDOWN;
        buttonstate |= SDL_BUTTON(button);
        break;
    case SDL_RELEASED:
        type = SDL_MOUSEBUTTONUP;
        buttonstate &= ~SDL_BUTTON(button);
        break;
    default:
        /* Invalid state -- bail */
        return 0;
    }

    /* We do this after calculating buttonstate so button presses gain focus */
    if (window && state == SDL_PRESSED) {
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
    }

    if (buttonstate == mouse->buttonstate) {
        /* Ignore this event, no state change */
        return 0;
    }
    mouse->buttonstate = buttonstate;

    if (clicks < 0) {
        SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
        if (clickstate) {
            if (state == SDL_PRESSED) {
                Uint32 now = SDL_GetTicks();

                if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + mouse->double_click_time) ||
                    SDL_abs(mouse->x - clickstate->last_x) > mouse->double_click_radius ||
                    SDL_abs(mouse->y - clickstate->last_y) > mouse->double_click_radius) {
                    clickstate->click_count = 0;
                }
                clickstate->last_timestamp = now;
                clickstate->last_x = mouse->x;
                clickstate->last_y = mouse->y;
                if (clickstate->click_count < 255) {
                    ++clickstate->click_count;
                }
            }
            clicks = clickstate->click_count;
        } else {
            clicks = 1;
        }
    }

    /* Post the event, if desired */
    posted = 0;
    if (SDL_GetEventState(type) == SDL_ENABLE) {
        SDL_Event event;
        event.type = type;
        event.button.windowID = mouse->focus ? mouse->focus->id : 0;
        event.button.which = mouseID;
        event.button.state = state;
        event.button.button = button;
        event.button.clicks = (Uint8) SDL_min(clicks, 255);
        event.button.x = mouse->x;
        event.button.y = mouse->y;
        posted = (SDL_PushEvent(&event) > 0);
    }

    /* We do this after dispatching event so button releases can lose focus */
    if (window && state == SDL_RELEASED) {
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
    }

    return posted;
}
Example #9
0
static void setEffect(DirectInputEffect *dinputEffect, const DIEFFECT *di_eff)
{
	uint32_t i;
	switch (dinputEffect->real_type)
	{
		case SDL_HAPTIC_CONSTANT:
		{
			DICONSTANTFORCE *di_constant = (DICONSTANTFORCE *)di_eff->typeSpecificParams;
			if (dinputEffect->effect.type == SDL_HAPTIC_SINE)
			{
				SDL_HapticPeriodic *periodic = &dinputEffect->effect.periodic;
				if (di_constant)
					periodic->magnitude = CONVERT(di_constant->magnitude);
				periodic->length = CONVERT_LENGTH(di_eff->duration);
// 				printf("Constant as Sine: %d, %d\n", periodic->length, periodic->magnitude);
			}
			else
			{
				SDL_HapticConstant *constant = &dinputEffect->effect.constant;
				if (di_constant)
					constant->level = CONVERT(di_constant->magnitude);
				constant->length = CONVERT_LENGTH(di_eff->duration);
				constant->direction.type = SDL_HAPTIC_POLAR; //di_eff->flags shows that POLAR is used (0x20)
				for (i = 0; i < di_eff->cAxes; ++i)
					constant->direction.dir[i] = di_eff->rglDirection[i];
// 				printf("Constant: %d %d %d, %X\n", constant->length, constant->level, di_eff->cAxes, di_eff->flags);
			}
		} break;
		case SDL_HAPTIC_SINE:
		{
			DIPERIODIC *di_periodic = (DIPERIODIC *)di_eff->typeSpecificParams;
			SDL_HapticPeriodic *periodic = &dinputEffect->effect.periodic;
			if (di_periodic)
			{
				periodic->magnitude = CONVERT(di_periodic->magnitude);
				periodic->offset = CONVERT(di_periodic->offset);
				periodic->period = (uint16_t)CONVERT_LENGTH(di_periodic->period);
				periodic->phase = di_periodic->phase;
			}
			periodic->length = CONVERT_LENGTH(di_eff->duration);
			if (di_eff->envelope)
				setEnvelope(&periodic->attack_length, &periodic->attack_level, &periodic->fade_length, &periodic->fade_level, di_eff->envelope);
// 			printf("Square as Sine: %d\n", periodic->magnitude);
		} break;
		case SDL_HAPTIC_SPRING:
		{
			/* Deadband always 0, Coeff and Saturation always the same */
			if (dinputEffect->effect.type == SDL_HAPTIC_SPRING)
			{
				/* Is it OK? I can't test it! */
				SDL_HapticCondition *condition = &dinputEffect->effect.condition;
				for (i = 0; i < di_eff->cAxes; ++i)
				{
					DICONDITION *di_condition = (DICONDITION *)di_eff->typeSpecificParams + i;
					condition->center[i] = CONVERT(di_condition->lOffset);
					condition->right_coeff[i] = CONVERT(di_condition->lPositiveCoefficient);
					condition->left_coeff[i] = CONVERT(di_condition->lNegativeCoefficient);
					condition->right_sat[i] = CONVERT(di_condition->dwPositiveSaturation);
					condition->left_sat[i] = CONVERT(di_condition->dwNegativeSaturation);
					condition->deadband[i] = CONVERT(di_condition->lDeadBand);
// 					printf("Spring[%d]: %d %d %d %d %d %d\n", i, condition->center[i], condition->right_coeff[i], condition->left_coeff[i], condition->right_sat[i], condition->left_sat[i], condition->deadband[i]);
				}
				condition->length = CONVERT_LENGTH(di_eff->duration);
			}
			else if (dinputEffect->effect.type == SDL_HAPTIC_CONSTANT && di_eff->cAxes)
			{
				/* Simulate Spring with Constant - this probably works bad :D */

				SDL_HapticConstant *constant = &dinputEffect->effect.constant;
				DICONDITION *di_condition = (DICONDITION *)di_eff->typeSpecificParams;

				int32_t axis = *dinputEffect->xAxis * 20000 / 65535 - 10000;
				int32_t force;
				if (*dinputEffect->xAxis > 0)
					force = di_condition->lPositiveCoefficient * (axis - di_condition->lOffset);
				else
					force = di_condition->lNegativeCoefficient * (axis - di_condition->lOffset);

				constant->direction.type = SDL_HAPTIC_CARTESIAN;
				constant->direction.dir[0] = (force == 0) ? 0 : (force < 0 ? -1 : 1);
				constant->attack_level = SDL_abs(force / 3052);
				constant->attack_length = (uint16_t)CONVERT_LENGTH(di_eff->duration);

// 				printf("Spring as Constant: coeffP: %d, coeffN: %d, offset: %d, xAxis: %d, force: %d, attack: %d\n", di_condition->lPositiveCoefficient, di_condition->lNegativeCoefficient, di_condition->lOffset, axis, force, force / 3052);
			}
		} break;
	}
}