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(&note);
84     else
85     {
86       track = tracks;
87       for (count=0;count<mod.tracks;count++)
88         get_track(track++,&note);
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