1 /*
2 * Copyright (C) 1990 Regents of the University of California.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee,
6 * provided that the above copyright notice appear in all copies and that
7 * both that copyright notice and this permission notice appear in
8 * supporting documentation, and that the name of the University of
9 * California not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior
11 * permission. the University of California makes no representations
12 * about the suitability of this software for any purpose. It is provided
13 * "as is" without express or implied warranty.
14 */
15
16 # include <X11/Intrinsic.h>
17 # include <stdio.h>
18
19 # include "debug.h"
20 # include "cdrom_globs.h"
21 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
22 # include "cdrom_freebsd.h"
23 #endif
24 #ifdef sun
25 # include "cdrom_sun.h"
26 #endif
27 #ifdef sgi
28 # include "cdrom_sgi.h"
29 #endif
30
31 # define ran(min, max) ((random() % ((max) - (min))) + (min))
32
33 static unsigned char *random_tracks;
34
35 extern AppData app_data;
36
37 void
shuffle_setup()38 shuffle_setup() {
39 extern char *malloc();
40 #ifdef sgi
41 extern time_t time(time_t *);
42 #else
43 extern long time();
44 #endif
45 extern long random();
46 unsigned long seed, now;
47 char state[128];
48 int try;
49 int i, j;
50
51 #if 0
52 if (cdi.state & CDROM_STATE_EJECTED) {
53 return;
54 }
55 #endif
56
57 if (cdi.maxtrack == cdi.mintrack) {
58 cdi.currand = -1;
59 return;
60 }
61
62 cdi.ntracks = (cdi.maxtrack - cdi.mintrack) + 1;
63
64 cdi.currand = 0;
65
66 if (random_tracks != NULL) {
67 free(random_tracks);
68 random_tracks = NULL;
69 }
70
71 if ((random_tracks = (unsigned char *) malloc(cdi.ntracks)) == NULL) {
72 perror("malloc");
73 exit(1);
74 }
75
76 now = time((long *) 0);
77 seed = now & 0xfff;
78
79 initstate(seed, state, sizeof(state));
80
81 /*
82 * set up the random_tracks array
83 */
84 for (i = 0; i < cdi.ntracks; i++) {
85 for (;;) {
86 try = ran(cdi.mintrack, cdi.maxtrack+1);
87
88 if (i == 0)
89 break;
90
91 for (j = 0; j < i; j++) {
92 if (random_tracks[j] == try)
93 goto again;
94 }
95
96 /* not a repeat */
97 break;
98
99 again:;
100 }
101
102 random_tracks[i] = try;
103 }
104
105 if (app_data.debug == True) {
106 debug_printf(1, "shuffle_setup: ");
107 for (i = 0; i < cdi.ntracks; i++)
108 debug_printf(1, "%d ", random_tracks[i]);
109 debug_printf(1, "\n");
110 }
111 }
112
113 unsigned char
shuffle_next_track()114 shuffle_next_track() {
115 if (cdi.currand == -1)
116 return(cdi.mintrack);
117
118 if (cdi.currand == cdi.ntracks) {
119 fprintf(stderr, "shuffle_get_track: ran off end\n");
120 return(cdi.mintrack);
121 }
122
123 return(random_tracks[cdi.currand++]);
124 }
125
126 unsigned char
shuffle_prev_track()127 shuffle_prev_track() {
128 if (cdi.currand == -1)
129 return(cdi.mintrack);
130
131 cdi.currand -= 2;
132
133 if (cdi.currand < 0)
134 cdi.currand = 0;
135
136 return(random_tracks[cdi.currand++]);
137 }
138