#include "coduo_x87emu.h" /* defines EMULATE_X87; x87 shim when it is 1 */

#include "cm_terrain_private.h"

qboolean CM_TerrainTraceThroughPlane(
    const vec4_t plane,
    const vec3_t start,
    const vec3_t end,
    float *enterFraction,
    float *leaveFraction,
    int32_t *enterPlaneChanged)
{
    *enterPlaneChanged = 0;

#if EMULATE_X87
    /* Each distance is one 80-bit chain — three products, two adds and the
     * -plane[3] — rounded once at its float slot. */
    const float startDistance = x87f_store_f32(x87f_sub(
        x87f_add(x87f_add(x87f_mul(x87f_load_f32(start[0]),
                                   x87f_load_f32(plane[0])),
                          x87f_mul(x87f_load_f32(start[1]),
                                   x87f_load_f32(plane[1]))),
                 x87f_mul(x87f_load_f32(start[2]), x87f_load_f32(plane[2]))),
        x87f_load_f32(plane[3])));
    const float endDistance = x87f_store_f32(x87f_sub(
        x87f_add(x87f_add(x87f_mul(x87f_load_f32(end[0]),
                                   x87f_load_f32(plane[0])),
                          x87f_mul(x87f_load_f32(end[1]),
                                   x87f_load_f32(plane[1]))),
                 x87f_mul(x87f_load_f32(end[2]), x87f_load_f32(plane[2]))),
        x87f_load_f32(plane[3])));
#else
    const float startDistance =
        (((start[0] * plane[0]) + (start[1] * plane[1])) +
         (start[2] * plane[2])) -
        plane[3];
    const float endDistance =
        (((end[0] * plane[0]) + (end[1] * plane[1])) +
         (end[2] * plane[2])) -
        plane[3];
#endif

    qboolean hit;

    if (!(startDistance > 0.0f) ||
        (!(endDistance >= 0.125f) && !(endDistance >= startDistance))) {
        if (!(0.0f >= startDistance) || !(0.0f >= endDistance)) {
            if (endDistance < startDistance) {
#if EMULATE_X87
                float fraction = x87f_store_f32(x87f_div(
                    x87f_sub(x87f_load_f32(startDistance),
                             x87f_load_f32(0.125f)),
                    x87f_sub(x87f_load_f32(startDistance),
                             x87f_load_f32(endDistance))));
#else
                float fraction =
                    (startDistance - 0.125f) / (startDistance - endDistance);
#endif
                if (fraction < 0.0f) {
                    fraction = 0.0f;
                }

                if (*enterFraction < fraction) {
                    *enterFraction = fraction;
                    *enterPlaneChanged = 1;
                }
            } else {
#if EMULATE_X87
                float fraction = x87f_store_f32(x87f_div(
                    x87f_add(x87f_load_f32(startDistance),
                             x87f_load_f32(0.125f)),
                    x87f_sub(x87f_load_f32(startDistance),
                             x87f_load_f32(endDistance))));
#else
                float fraction =
                    (startDistance + 0.125f) / (startDistance - endDistance);
#endif
                if (fraction > 1.0f) {
                    fraction = 1.0f;
                }

                if (fraction < *leaveFraction) {
                    *leaveFraction = fraction;
                }
            }

            hit = 1;
        } else {
            hit = 1;
        }
    } else {
        hit = 0;
    }

    return hit;
}
