1 /***************************************************************************
2 * S3m/Mod player by Daniel Marks (dmarks@ais.net)
3 * GUS support by David Jeske (jeske@uiuc.edu)
4 *
5 * (C) 1994,1995 By Daniel Marks and David Jeske
6 *
7 * While we retain the copyright to this code, this source code is FREE.
8 * You may use it in any way you wish, in any product you wish. You may
9 * NOT steal the copyright for this code from us.
10 *
11 * We respectfully ask that you email one of us, if possible, if you
12 * produce something significant with this code, or if you have any bug
13 * fixes to contribute. We also request that you give credit where
14 * credit is due if you include part of this code in a program of your own.
15 *
16 * Email: s3mod@uiuc.edu
17 * jeske@uiuc.edu
18 *
19 * See the associated README file for Thanks
20 ***************************************************************************
21 *
22 * play.c - the player itself
23 *
24 */
25
26 #include "config.h"
27
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <fcntl.h>
32
33 #include "main.h"
34 #include "mod.h"
35 #include "play.h"
36 #include "dsp.h"
37
38 #ifdef GUS
39 #include <machine/ultrasound.h>
40 #include "gus.h"
41 #endif /* GUS */
42
43
44 union
45 {
46 uint8 rot_buf[ROT_BUF_SIZE];
47 uint16 rot_buf16[ROT_BUF_SIZE];
48 } buf;
49
updatetracks(void)50 void updatetracks(void)
51 {
52 track_info_ptr track;
53 int16 count;
54
55 tempo_wait = tempo;
56 if (row >= 64)
57 {
58 if (order_pos >= mod.song_length_patterns)
59 {
60 order_pos = mod.song_repeat_patterns;
61 if (order_pos >= mod.song_length_patterns)
62 {
63 order_pos = 0;
64 mod_done = 1;
65 }
66 }
67 row = break_row;
68 break_row = 0;
69 if (mod.positions[order_pos] == 0xFF)
70 {
71 mod_done = 1;
72 return;
73 }
74 if (mod.s3m)
75 note = mod.patterns[mod.positions[order_pos]];
76 else
77 note = mod.patterns[mod.positions[order_pos]] +
78 (((uint16)row) * sizeof(uint8) * 4 * mod.tracks);
79 order_pos++;
80 }
81 row++;
82 if (mod.s3m)
83 get_track_s3m(¬e);
84 else
85 {
86 track = tracks;
87 for (count=0;count<mod.tracks;count++)
88 get_track(track++,¬e);
89
90 }
91 track = tracks;
92 for (count=0;count<mod.tracks;count++)
93 {
94 track->playing_period = track->period;
95 track->playing_volume = track->volume;
96 track++;
97 }
98
99 #ifdef DEBUG
100 printf("00-01-02-03-04-05-06-07-pattern %d row %d\n",order_pos,row);
101 #endif
102 return;
103 }
104
105
play_mod(int loud)106 void play_mod(int loud)
107 {
108 register uint8 *c;
109 register uint16 *d;
110 int16 i;
111 track_info_ptr track;
112 int16 count;
113
114 startplaying(loud);
115 mod_done = 0;
116 while (!mod_done)
117 {
118 if (--tempo_wait)
119 {
120 track = tracks;
121 for (count=0;count<mod.tracks;count++)
122 beattrack(track++);
123 }
124 else
125 updatetracks();
126
127 track = tracks;
128 if (bit16)
129 {
130 if (stereo)
131 for (d=&buf.rot_buf16[bpm_samples << 1];d > buf.rot_buf16;*(--d) = 0x8000);
132 else
133 for (d=&buf.rot_buf16[bpm_samples];d > buf.rot_buf16;*(--d) = 0x8000);
134 } else
135 {
136 if (stereo)
137 for (c=&buf.rot_buf[bpm_samples << 1];c > buf.rot_buf;*(--c) = 0x80);
138 else
139 for (c=&buf.rot_buf[bpm_samples];c > buf.rot_buf;*(--c) = 0x80);
140 }
141 for (i=0;i<mod.tracks;i++)
142 {
143
144 if (bit16)
145 {
146 if (stereo)
147 mixtrack_16_stereo(track,buf.rot_buf16,bpm_samples,
148 i & 0x01);
149 else
150 mixtrack_16_mono(track,buf.rot_buf16,bpm_samples);
151 } else
152 {
153 if (stereo)
154 mixtrack_8_stereo(track,buf.rot_buf,bpm_samples,
155 i & 0x01);
156 else
157 mixtrack_8_mono(track,buf.rot_buf,bpm_samples);
158 }
159 track++;
160 }
161 c = (uint8 *) buf.rot_buf;
162 if (stereo)
163 {
164 if (bit16)
165 d = (uint16 *) &c[bpm_samples << 2];
166 else
167 d = (uint16 *) &c[bpm_samples << 1];
168 } else
169 {
170 if (bit16)
171 d = (uint16 *) &c[bpm_samples << 1];
172 else
173 d = (uint16 *) &c[bpm_samples];
174 }
175 while (c < ((uint8 *)d))
176 {
177 if (audio_curptr >= audio_end_buffer)
178 {
179 write_dsp_device(audio_start_buffer,audio_buffer_size);
180 audio_curptr = audio_start_buffer;
181 }
182 *audio_curptr++ = *c++;
183 }
184 }
185 }
186