Update interpreters to latest Garglk codebase
[projects/chimara/chimara.git] / interpreters / frotz / random.c
1 /* random.c - Z-machine random number generator
2  *      Copyright (c) 1995-1997 Stefan Jokisch
3  *
4  * This file is part of Frotz.
5  *
6  * Frotz is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Frotz is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "frotz.h"
22
23 static long A = 1;
24
25 static int interval = 0;
26 static int counter = 0;
27
28 /*
29  * seed_random
30  *
31  * Set the seed value for the random number generator.
32  *
33  */
34
35 void seed_random (int value)
36 {
37
38     if (value == 0) {           /* ask interface for seed value */
39         A = os_random_seed ();
40         interval = 0;
41     } else if (value < 1000) {  /* special seed value */
42         counter = 0;
43         interval = value;
44     } else {                    /* standard seed value */
45         A = value;
46         interval = 0;
47     }
48
49 }/* seed_random */
50
51 /*
52  * z_random, store a random number or set the random number seed.
53  *
54  *      zargs[0] = range (positive) or seed value (negative)
55  *
56  */
57
58 void z_random ()
59 {
60
61     if ((short) zargs[0] <= 0) {        /* set random seed */
62
63         seed_random (- (short) zargs[0]);
64         store (0);
65
66     } else {                            /* generate random number */
67
68         zword result;
69
70         if (interval != 0) {            /* ...in special mode */
71             result = counter++;
72             if (counter == interval) counter = 0;
73         } else {                        /* ...in standard mode */
74             A = 0x015a4e35L * A + 1;
75             result = (A >> 16) & 0x7fff;
76         }
77
78         store ((zword) (result % zargs[0] + 1));
79
80     }
81
82 }/* z_random */