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