void handle_touch_events()

in libs/hw---vm/sdlmain.cpp [232:312]


void handle_touch_events(SDL_Event &e) {
    if (e.type == SDL_FINGERDOWN || e.type == SDL_FINGERUP || e.type == SDL_FINGERMOTION) {
        SDL_Point p;
        p.x = e.tfinger.x * win_width;
        p.y = e.tfinger.y * win_height;

        int i, firstFree = -1;
        for (i = 0; i < NUM_FINGERS; ++i) {
            if (fingers[i].lastKey) {
                if (fingers[i].fingerId == e.tfinger.fingerId)
                    break;
            } else {
                if (firstFree == -1)
                    firstFree = i;
            }
        }

        if (e.type == SDL_FINGERUP) {
            if (i != NUM_FINGERS)
                fingers[i].lastKey = NULL;
        } else {
            if (i == NUM_FINGERS) {
                i = firstFree;
                if (i == -1)
                    fatal("too many fingers?");
            }
            fingers[i].fingerId = e.tfinger.fingerId;
            auto nearest = &keys[0];
            auto nearestDistance = -1;
            for (int j = 0; j < NUM_KEYS; ++j) {
                auto dist = distance(p, keys[j].center);
                if (nearestDistance == -1 || nearestDistance > dist) {
                    nearestDistance = dist;
                    nearest = &keys[j];
                }
            }

            fingers[i].secondLastKey = NULL;
            auto minDistance = (win_height / 5) * (win_height / 5);
            if (nearestDistance > minDistance)
                nearest = NULL;
            else {
                auto secondNearest = &keys[0];
                auto secondNearestDist = -1;
                for (int j = 0; j < NUM_KEYS; ++j) {
                    if (&keys[j] == nearest)
                        continue;
                    auto dist = distance(p, keys[j].center);
                    if (secondNearestDist == -1 || secondNearestDist > dist) {
                        secondNearestDist = dist;
                        secondNearest = &keys[j];
                    }
                }

                auto maxDist = nearestDistance * 16 / 10;
                if (secondNearestDist < maxDist) {
                    fingers[i].secondLastKey = secondNearest;
                }
            }

            fingers[i].lastKey = nearest;
        }

        for (int j = 0; j < NUM_KEYS; ++j) {
            keys[j].prevPressed = keys[j].isPressed;
            keys[j].isPressed = false;
        }

        for (int i = 0; i < NUM_FINGERS; ++i) {
            if (fingers[i].lastKey)
                fingers[i].lastKey->isPressed = true;
            if (fingers[i].secondLastKey)
                fingers[i].secondLastKey->isPressed = true;
        }

        for (int j = 0; j < NUM_KEYS; ++j) {
            if (keys[j].prevPressed != keys[j].isPressed)
                raise_key(keys[j].keyId, keys[j].isPressed ? INTERNAL_KEY_DOWN : INTERNAL_KEY_UP);
        }
    }
}