{****************************************************************************
*                      The DOOM Hacker's Tool Kit                           *
*****************************************************************************
* Unit: 	  SOUNDS                                                           *
* Purpose: Loading and Playing WAD file sounds                              *
* Date:    4/28/94                                                          *
* Author:  Joshua Jackson        Internet: joshjackson@delphi.com           *
****************************************************************************}

unit Sounds;

interface

uses Wad,WadDecl,Crt;

Type 	PSoundDef=^TSoundDef;
		TSoundDef=object
			Constructor Init(WDir:PWadDirectory;SndName:ObjNameStr);
			Procedure PlaySound;
         Function IsComplete:boolean;
			Procedure EndSound;
			Destructor Done;
		 Private
			SoundBuff:PSoundBuff;
			IsPlaying:Boolean;
			sbBuff:word;
		end;

implementation

{$IFDEF DPMI}
	uses DPMI,Sounder2,ObjCache;
{$ELSE}
	uses Sounder2,ObjCache;
{$ENDIF}

type TBuff=Array[0..46080] of byte;

var 	BuffPtr:^TBuff;

Constructor TSoundDef.Init(WDir:PWadDirectory;SndName:ObjNameStr);

	var 	l:word;

	begin
		l:=WDir^.FindObject(SndName);
		if l=0 then begin
			if TerminateOnWadError then begin
				TextMode(co80);
				writeln('ReadSound: Could not locate sound ID: ',SndName);
				halt(1);
			 end
			else begin
				WadResult:=wrNoSound;
				exit;
			end;
		end;
		seek(WDir^.WadFile,WDir^.DirEntry^[l].ObjStart);
		New(SoundBuff);						{Allocate New Sound Descriptor}
      BlockRead(WDir^.WadFile,SoundBuff^,8);
      GetMem(SoundBuff^.Sound, SoundBuff^.Samples);
      BlockRead(WDir^.WadFile,SoundBuff^.Sound^,SoundBuff^.Samples);
		IsPlaying:=False;
	end;

Procedure TSoundDef.PlaySound;

	var	TempAddr:word;
			MemSize:word;
			BuffAddr:longint;

	begin
		if IsPlaying then
			EndSound;
	{$IFDEF DPMI}
		MemSize:=(SoundBuff^.Samples div 16) + 1;
		AllocDosMem(MemSize,SbBuff,TempAddr);			{Allocate DMA Buffer}
		BuffPtr:=ptr(SbBuff,0);
		BuffAddr:=TempAddr;
		BuffAddr:=longint(BuffAddr) shl 4;
		move(SoundBuff^.Sound^[0],BuffPtr^[0],SoundBuff^.Samples);
	{$ELSE}
      BuffPtr:=@SoundBuff^.Sound^;
		BuffAddr:=(longint(Seg(BuffPtr^)) shl 4) + Ofs(BuffPtr^);
	{$ENDIF}
		InitSB;
		PlayBuff(SoundBuff,BuffAddr);
		IsPlaying:=True;
	end;

Function TSoundDef.IsComplete;

	begin
   	IsComplete:=DMA_Complete;
   end;

Procedure TSoundDef.EndSound;

	begin
		if not IsPlaying then
			exit;
		StopBuff;
	{$IFDEF DPMI}
		DeAllocDosMem(sbBuff);						{Dispose DMA Buffer}
	{$ENDIF}
		IsPlaying:=False;
	end;

Destructor TSoundDef.Done;

	begin
		FreeMem(SoundBuff^.Sound,SoundBuff^.Samples); {Dispose Sound Data}
		Dispose(SoundBuff);				{Dispose Sound Descriptor}
	end;

end.