/*
    Copyright (C) 1995-2016, The AROS Development Team. All rights reserved.

    C99 functions rand() and srand().
*/

#include "__stdc_intbase.h"

#include <aros/symbolsets.h>

/*****************************************************************************

    NAME */
#include <stdlib.h>

        int rand (

/*  SYNOPSIS */
        void)

/*  FUNCTION
        A random number generator.

    INPUTS
        None.

    RESULT
        A pseudo-random integer between 0 and RAND_MAX.

    NOTES

    EXAMPLE

    BUGS

    SEE ALSO
        srand()

    INTERNALS

******************************************************************************/
{
    struct StdCIntBase *StdCBase = (struct StdCIntBase *)__aros_getbase_StdCBase();

    StdCBase->srand_seed = StdCBase->srand_seed * 1103515245 + 12345;

    return StdCBase->srand_seed % RAND_MAX;
} /* rand */


/*****************************************************************************

    NAME */
#include <stdlib.h>

        void srand (

/*  SYNOPSIS */
        unsigned int seed)

/*  FUNCTION
        Set the starting value for the random number generator rand()
        If a seed value is set to a value the same stream of pseudo-random
        numbers will be generated by rand() for the same seed value.

    INPUTS
        seed - New start value

    RESULT
        None.

    NOTES
        One seed value per stdc.library is kept which normally corresponds
        with per task.

    EXAMPLE

    BUGS

    SEE ALSO
        rand()

    INTERNALS

******************************************************************************/
{
    struct StdCIntBase *StdCBase = (struct StdCIntBase *)__aros_getbase_StdCBase();

    StdCBase->srand_seed = seed;
} /* srand */

static int __rand_seedinit(struct StdCIntBase *StdCBase)
{
    // use Xorshift with the suggested coefficients by Marsaglia for
    // a 32-bit generator (13, 17, 5)   to set our initial seed.
    StdCBase->srand_seed = time(NULL);
    StdCBase->srand_seed ^= StdCBase->srand_seed >> 13; // a
    StdCBase->srand_seed ^= StdCBase->srand_seed << 17; // b
    StdCBase->srand_seed ^= StdCBase->srand_seed >> 5; // c

    return 1;
}

ADD2OPENLIB(__rand_seedinit, 0);
