+ *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[6], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[7], 32767);
+ }
+ }
+ else if (rb->format.channels == 6) // 5.1 surround
+ {
+ for (i = 0; i < nbframes; i++, painted_ptr++)
+ {
+ *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
+ }
+ }
+ else if (rb->format.channels == 4) // 4.0 surround
+ {
+ for (i = 0; i < nbframes; i++, painted_ptr++)
+ {
+ *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
+ }
+ }
+ else if (rb->format.channels == 2) // 2.0 stereo
+ {
+ for (i = 0; i < nbframes; i++, painted_ptr++)
+ {
+ *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
+ *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
+ }
+ }
+ else if (rb->format.channels == 1) // 1.0 mono
+ {
+ for (i = 0; i < nbframes; i++, painted_ptr++)
+ {
+ val = (painted_ptr->sample[0] + painted_ptr->sample[1]) >> 1;
+ *snd_out++ = bound(-32768, val, 32767);
+ }
+ }
+ }
+ else // 8bit
+ {
+ unsigned char *snd_out = (unsigned char*)rb_ptr;
+ if (rb->format.channels == 8) // 7.1 surround
+ {
+ for (i = 0; i < nbframes; i++, painted_ptr++)
+ {
+ val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[6] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[7] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ }
+ }
+ else if (rb->format.channels == 6) // 5.1 surround
+ {
+ for (i = 0; i < nbframes; i++, painted_ptr++)
+ {
+ val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ }
+ }
+ else if (rb->format.channels == 4) // 4.0 surround
+ {
+ for (i = 0; i < nbframes; i++, painted_ptr++)
+ {
+ val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ }
+ }
+ else if (rb->format.channels == 2) // 2.0 stereo
+ {
+ for (i = 0; i < nbframes; i++, painted_ptr++)
+ {
+ val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+ }
+ }
+ else if (rb->format.channels == 1) // 1.0 mono
+ {
+ for (i = 0;i < nbframes;i++, painted_ptr++)
+ {
+ val = ((painted_ptr->sample[0] + painted_ptr->sample[1]) >> 9) + 128;
+ *snd_out++ = bound(0, val, 255);
+ }
+ }
+ }
+
+ partialend += nbframes;
+ }
+
+ rb->endframe = endtime;
+
+ // Remove outdated samples from the ring buffer, if any
+ if (rb->startframe < soundtime)
+ rb->startframe = soundtime;
+
+ if (!simsound)
+ SndSys_UnlockRenderBuffer();
+
+ return endtime - starttime;
+}
+
+
+/*
+===============================================================================
+
+CHANNEL MIXING
+
+===============================================================================
+*/
+
+static qboolean SND_PaintChannel (channel_t *ch, unsigned int count)
+{
+ int snd_vol, vol[SND_LISTENERS];
+ const snd_buffer_t *sb;
+ unsigned int i, sb_offset;
+
+ // If this channel manages its own volume
+ if (ch->flags & CHANNELFLAG_FULLVOLUME)
+ snd_vol = 256;
+ else
+ snd_vol = (int)(volume.value * 256);
+
+ for (i = 0;i < SND_LISTENERS;i++)
+ vol[i] = ch->listener_volume[i] * snd_vol;
+
+ sb_offset = ch->pos;
+ sb = ch->sfx->fetcher->getsb (ch, &sb_offset, count);
+ if (sb == NULL)
+ {
+ Con_DPrintf("SND_PaintChannel: ERROR: can't get sound buffer from sfx \"%s\"\n",
+ ch->sfx->name, count);
+ }
+ else
+ {
+#if SND_LISTENERS != 8
+# error the following code only supports up to 8 channels, update it
+#endif
+ if (sb->format.width == 1)
+ {
+ const signed char *samples = (signed char*)sb->samples + (ch->pos - sb_offset) * sb->format.channels;
+
+ // Stereo sound support
+ if (sb->format.channels == 2)
+ {
+ if (vol[6] + vol[7] > 0)
+ {
+ for (i = 0;i < count;i++)