⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snd_mix.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  ps: playsound_p;
  s, stop: Integer;
begin
  snd_vol := Trunc(s_volume^.value * 256);

  //Com_Printf ("%i to %i\n", paintedtime, endtime);
  while (paintedtime < endtime) do
  begin
    // if paintbuffer is smaller than DMA buffer
    _end := endtime;
    if (endtime - paintedtime > PAINTBUFFER_SIZE) then
      _end := paintedtime + PAINTBUFFER_SIZE;

    // start any playsounds
    while (True) do
    begin
      ps := s_pendingplays.next;
      if (ps = @s_pendingplays) then
        break;                          // no more pending sounds
      if (ps^._begin <= paintedtime) then
      begin
        S_IssuePlaysound(ps);
        continue;
      end;

      if (ps^._begin < _end) then
        _end := ps^._begin;             // stop here
      break;
    end;

    // clear the paint buffer
    if (s_rawend < paintedtime) then
    begin
      //			Com_Printf ("clear\n");
      FillChar(paintbuffer, (_end - paintedtime) * sizeof(portable_samplepair_t), 0);
    end
    else
    begin                               // copy from the streaming sound source
      //stop := (_end < s_rawend) ? _end : s_rawend;
      if (_end < s_rawend) then
        stop := _end
      else
        stop := s_rawend;

      for i := paintedtime to stop - 1 do
      begin
        s := i and (MAX_RAW_SAMPLES - 1);
        paintbuffer[i - paintedtime] := s_rawsamples_[s];
      end;
      //		if (i != end)
      //			Com_Printf ("partial stream\n");
      //		else
      //			Com_Printf ("full stream\n");
      for i := stop to _end - 1 do
      begin
        paintbuffer[i - paintedtime].left := 0;
        paintbuffer[i - paintedtime].right := 0;
      end;
    end;

    // paint in the channels.
    for i := 0 to MAX_CHANNELS - 1 do   //i++, ch++)
    begin
      ltime := paintedtime;

      while (ltime < _end) do
      begin
        if ((channels[i].sfx = nil) or ((channels[i].leftvol = 0) and (channels[i].rightvol = 0))) then
          break;

        // max painting is to the end of the buffer
        count := _end - ltime;

        // might be stopped by running out of data
        if (channels[i]._end - ltime < count) then
          count := channels[i]._end - ltime;

        sc := S_LoadSound(channels[i].sfx);
        if (sc = nil) then
          break;

        if ((count > 0) and (channels[i].sfx <> nil)) then
        begin
          if (sc^.width = 1) then       // FIXME; 8 bit asm is wrong now
            S_PaintChannelFrom8(@channels[i], sc, count, ltime - paintedtime)
          else
            S_PaintChannelFrom16(@channels[i], sc, count, ltime - paintedtime);

          Inc(ltime, count);
        end;

        // if at end of loop, restart
        if (ltime >= channels[i]._end) then
        begin
          if (channels[i].autosound) then
          begin                         // autolooping sounds always go back to start
            channels[i].pos := 0;
            channels[i]._end := ltime + sc^.length;
          end
          else if (sc^.loopstart >= 0) then
          begin
            channels[i].pos := sc^.loopstart;
            channels[i]._end := ltime + sc^.length - channels[i].pos;
          end
          else
          begin                         // channel just stopped
            channels[i].sfx := nil;
          end;
        end;
      end;

    end;

    // transfer out according to DMA format
    S_TransferPaintBuffer(_end);
    paintedtime := _end;
  end;
end;

procedure S_InitScaletable;
var
  i, j, scale: Integer;
begin
  s_volume^.modified := false;
  for i := 0 to 31 do
  begin
    scale := Trunc(i * 8 * 256 * s_volume^.value);
    for j := 0 to 255 do
      snd_scaletable[i][j] := ShortInt(j) * scale;
  end;
end;

procedure S_PaintChannelFrom8(ch: channel_p; sc: sfxcache_p; count, offset: Integer);
var
  data, i: Integer;
  lscale, rscale: PIntegerArray;
  sfx: PByteArray;
  samp: portable_samplepair_p;
begin
  if (ch^.leftvol > 255) then
    ch^.leftvol := 255;
  if (ch^.rightvol > 255) then
    ch^.rightvol := 255;

  //ZOID--  shr 11 has been changed to  shr 3,  shr 11 didn't make much sense
  //as it would always be zero.
  lscale := @snd_scaletable[ch^.leftvol shr 3];
  rscale := @snd_scaletable[ch^.rightvol shr 3];
  sfx := Pointer(Cardinal(@sc^.data) + ch^.pos);

  samp := @paintbuffer[offset];
  for i := 0 to count - 1 do
  begin
    data := sfx[i];
    samp.left := samp.left + lscale[data];
    samp.right := samp.right + rscale[data];
    Inc(samp);
  end;

  ch^.pos := ch^.pos + count;
end;

(*
procedure S_PaintChannelFrom8(ch : channel_p; sc : sfxcache_p; count, offset: Integer);
asm
 push esi
 push edi
 push ebx
 push ebp
 mov ebx,ds:dword ptr[4+16+esp]
 mov esi,ds:dword ptr[8+16+esp]
 mov eax,ds:dword ptr[4+ebx]
 mov edx,ds:dword ptr[8+ebx]
 cmp eax,255
 jna @LLeftSet
 mov eax,255
@LLeftSet:
 cmp edx,255
 jna @LRightSet
 mov edx,255
@LRightSet:
 and eax,0F8h
 add esi,20
 and edx,0F8h
 mov edi,ds:dword ptr[16+ebx]
 mov ecx,ds:dword ptr[12+16+esp]
 add esi,edi
 shl eax,7
 add edi,ecx
 shl edx,7
 mov ds:dword ptr[16+ebx],edi
 add eax,offset snd_scaletable
 add edx,offset snd_scaletable
 sub ebx,ebx
 mov bl,ds:byte ptr[-1+esi+ecx*1]
 test ecx,1
 jz @LMix8Loop
 mov edi,ds:dword ptr[eax+ebx*4]
 mov ebp,ds:dword ptr[edx+ebx*4]
 add edi,ds:dword ptr[paintbuffer+0-8+ecx*8]
 add ebp,ds:dword ptr[paintbuffer+4-8+ecx*8]
 mov ds:dword ptr[paintbuffer+0-8+ecx*8],edi
 mov ds:dword ptr[paintbuffer+4-8+ecx*8],ebp
 mov bl,ds:byte ptr[-2+esi+ecx*1]
 dec ecx
 jz @LDone
@LMix8Loop:
 mov edi,ds:dword ptr[eax+ebx*4]
 mov ebp,ds:dword ptr[edx+ebx*4]
 add edi,ds:dword ptr[paintbuffer+0-8+ecx*8]
 add ebp,ds:dword ptr[paintbuffer+4-8+ecx*8]
 mov bl,ds:byte ptr[-2+esi+ecx*1]
 mov ds:dword ptr[paintbuffer+0-8+ecx*8],edi
 mov ds:dword ptr[paintbuffer+4-8+ecx*8],ebp
 mov edi,ds:dword ptr[eax+ebx*4]
 mov ebp,ds:dword ptr[edx+ebx*4]
 mov bl,ds:byte ptr[-3+esi+ecx*1]
 add edi,ds:dword ptr[paintbuffer+0-8*2+ecx*8]
 add ebp,ds:dword ptr[paintbuffer+4-8*2+ecx*8]
 mov ds:dword ptr[paintbuffer+0-8*2+ecx*8],edi
 mov ds:dword ptr[paintbuffer+4-8*2+ecx*8],ebp
 sub ecx,2
 jnz @LMix8Loop
@LDone:
 pop ebp
 pop ebx
 pop edi
 pop esi
 ret
end;
*)

procedure S_PaintChannelFrom16(ch: channel_p; sc: sfxcache_p; count, offset: Integer);
var
  data,
    left,
    right,
    leftvol,
    rightvol,
    i: Integer;
  sfx: PSmallIntArray;
  samp: portable_samplepair_p;
begin
  leftvol := ch^.leftvol * snd_vol;
  rightvol := ch^.rightvol * snd_vol;
  sfx := Pointer(Cardinal(@sc^.data) + ch^.pos * SizeOf(SmallInt));

  samp := @paintbuffer[offset];
  for i := 0 to count - 1 do
  begin
    data := sfx[i];
    asm
      mov edi, data

      // left = (data * leftvol)>>8;
      mov  eax, edi // data
      imul leftvol
      sar  eax, 8
      mov  left, eax

      // right = (data * rightvol)>>8;
      mov  eax, edi // data
      imul rightvol
      sar  eax, 8
      mov  right, eax
    end;
    samp.left := samp.left + left;
    samp.right := samp.right + right;
    Inc(samp);
  end;

  ch^.pos := ch^.pos + count;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -