Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 1
#include "std.h"
2
 
3
#include "emul.h"
4
#include "vars.h"
5
#include "bass.h"
6
#include "snd_bass.h"
7
#include "gshle.h"
8
#include "gs.h"
9
#include "init.h"
10
#include "util.h"
11
 
12
#ifdef MOD_GSBASS
13
void GSHLE::reportError(const char *err, bool fatal)
14
{
15
   color(CONSCLR_ERROR);
16
   printf("BASS library reports error in %s\n", err);
17
   color(CONSCLR_ERRCODE);
18
   printf("error code is 0x%04X\n", BASS::ErrorGetCode());
19
   if(fatal)
20
   {
21
       exit();
22
   }
23
}
24
 
25
void GSHLE::runBASS()
26
{
27
   static bool Initialized = false;
28
 
29
   if(Initialized)
30
       return;
31
 
32
   if (BASS::Init(-1, conf.sound.fq, BASS_DEVICE_LATENCY, wnd, 0))
33
   {
34
      DWORD len = BASS::GetConfig(BASS_CONFIG_UPDATEPERIOD);
35
      BASS_INFO info;
36
      BASS::GetInfo(&info);
37
      BASS::SetConfig(BASS_CONFIG_BUFFER, len + info.minbuf);
38
      color(CONSCLR_HARDITEM);
39
      printf("BASS device latency is ");
40
      color(CONSCLR_HARDINFO);
41
      printf("%lums\n", len + info.minbuf);
42
   }
43
   else
44
   {
45
      color(CONSCLR_WARNING);
46
      printf("warning: can't use default BASS device, trying silence\n");
47
      if (!BASS::Init(-2, 11025, 0, wnd, 0))
48
          errexit("can't init BASS");
49
   }
50
 
51
   Initialized = true;
52
   hmod = 0;
53
   for (int ch = 0; ch < 4; ch++)
54
       chan[ch].bass_ch = 0;
55
}
56
 
57
void GSHLE::reset_sound()
58
{
59
  // runBASS();
60
  // BASS_Stop(); // todo: move to silent state?
61
}
62
 
63
 
64
DWORD CALLBACK gs_render(HSTREAM handle, void *buffer, DWORD length, void *user);
65
 
66
void GSHLE::initChannels()
67
{
68
   if (chan[0].bass_ch)
69
       return;
70
   for (int ch = 0; ch < 4; ch++)
71
   {
72
      chan[ch].bass_ch = BASS::StreamCreate(11025, 1, BASS_SAMPLE_8BITS, gs_render, &chan[ch]);
73
      if (!chan[ch].bass_ch)
74
          reportError("BASS_StreamCreate()");
75
   }
76
}
77
 
78
void GSHLE::setmodvol(unsigned vol)
79
{
80
   if (!hmod)
81
       return;
82
   runBASS();
83
   float v = (vol * conf.sound.bass_vol) / float(8000 * 64);
84
   assert(v<=1.0);
85
   if (!BASS::ChannelSetAttribute(hmod, BASS_ATTRIB_VOL, v))
86
       reportError("BASS_ChannelSetAttribute() [music volume]");
87
}
88
 
89
void GSHLE::init_mod()
90
{
91
   runBASS();
92
   if (hmod)
93
       BASS::MusicFree(hmod);
94
   hmod = 0;
95
   hmod = BASS::MusicLoad(1, mod, 0, modsize, BASS_MUSIC_LOOP | BASS_MUSIC_POSRESET | BASS_MUSIC_RAMP, 0);
96
   if (!hmod)
97
       reportError("BASS_MusicLoad()", false);
98
}
99
 
100
void GSHLE::restart_mod(unsigned order, unsigned row)
101
{
102
   if (!hmod)
103
       return;
104
   if (!BASS::ChannelSetPosition(hmod, MAKELONG(order,row), BASS_POS_MUSIC_ORDER))
105
       reportError("BASS_ChannelSetPosition() [music]");
106
   if (!BASS::ChannelFlags(hmod, BASS_MUSIC_LOOP | BASS_MUSIC_POSRESET | BASS_MUSIC_RAMP, -1))
107
       reportError("BASS_ChannelFlags() [music]");
108
   BASS::Start();
109
   if (!BASS::ChannelPlay(hmod, FALSE/*TRUE*/))
110
       reportError("BASS_ChannelPlay() [music]"); //molodcov_alex 0.36.2
111
 
112
   mod_playing = 1;
113
}
114
 
115
void GSHLE::resetmod()
116
{
117
   if (hmod)
118
       BASS::MusicFree(hmod);
119
   hmod = 0;
120
}
121
 
122
void GSHLE::resetfx()
123
{
124
   runBASS();
125
   for (int i = 0; i < 4; i++)
126
   {
127
       if (chan[i].bass_ch)
128
       {
129
         BASS::StreamFree(chan[i].bass_ch);
130
         chan[i].bass_ch = 0;
131
       }
132
   }
133
}
134
 
135
DWORD GSHLE::modgetpos()
136
{
137
   runBASS();
138
   return (DWORD)BASS::ChannelGetPosition(hmod, BASS_POS_MUSIC_ORDER);
139
//   return BASS_MusicGetOrderPosition(hmod);
140
}
141
 
142
void GSHLE::stop_mod()
143
{
144
   runBASS();
145
   if (!hmod)
146
       return;
147
   if(BASS::ChannelIsActive(hmod) != BASS_ACTIVE_PLAYING)
148
       return;
149
   if (!BASS::ChannelPause(hmod))
150
       reportError("BASS_ChannelPause() [music]");
151
}
152
 
153
void GSHLE::cont_mod()
154
{
155
   runBASS();
156
   if (!hmod)
157
       return;
158
   if (!BASS::ChannelPlay(hmod, TRUE))
159
       reportError("BASS_ChannelPlay() [music]");
160
}
161
 
162
void GSHLE::startfx(CHANNEL *ch, float pan)
163
{
164
   initChannels();
165
 
166
   float vol = (ch->volume * conf.sound.gs_vol) / float(8000*64);
167
   if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_VOL, vol))
168
       reportError("BASS_ChannelSetAttribute() [vol]");
169
   if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_FREQ, float(ch->freq)))
170
       reportError("BASS_ChannelSetAttribute() [freq]");
171
   if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_PAN, pan))
172
       reportError("BASS_ChannelSetAttribute() [pan]");
173
 
174
   if (!BASS::ChannelPlay(ch->bass_ch, FALSE))
175
       reportError("BASS_ChannelPlay()");
176
}
177
 
178
void GSHLE::flush_gs_frame()
179
{
180
   unsigned lvl;
181
   if (!hmod || (lvl = BASS::ChannelGetLevel(hmod)) == -1) lvl = 0;
182
 
183
   gsleds[0].level = LOWORD(lvl) >> (15-4);
184
   gsleds[0].attrib = 0x0D;
185
   gsleds[1].level = HIWORD(lvl) >> (15-4);
186
   gsleds[1].attrib = 0x0D;
187
 
188
   for (int ch = 0; ch < 4; ch++)
189
   {
190
      if (chan[ch].bass_ch && (lvl = BASS::ChannelGetLevel(chan[ch].bass_ch)) != -1)
191
      {
192
         lvl = max(HIWORD(lvl), LOWORD(lvl));
193
         lvl >>= (15-4);
194
      }
195
      else
196
         lvl = 0;
197
      gsleds[ch+2].level = lvl;
198
      gsleds[ch+2].attrib = 0x0F;
199
   }
200
}
201
 
202
void GSHLE::debug_note(unsigned i)
203
{
204
   GSHLE::CHANNEL ch = { 0 };
205
   ch.volume = 64; ch.ptr = 0;
206
   ch.start = sample[i].start;
207
   ch.loop = sample[i].loop;
208
   ch.end = sample[i].end;
209
   unsigned note = sample[i].note; if (note == 60) note = 50;
210
   ch.freq = note2rate[note];
211
   ch.bass_ch = BASS::StreamCreate(11025, 1, BASS_SAMPLE_8BITS, gs_render, &ch);
212
   startfx(&ch, 0);
213
   unsigned mx = (sample[i].loop < sample[i].end)? 5000 : 10000;
214
   for (unsigned j = 0; j < mx/256; j++)
215
   {
216
      if (!ch.start)
217
          break;
218
      Sleep(256);
219
   }
220
   BASS::StreamFree(ch.bass_ch);
221
}
222
#endif