diff options
39 files changed, 4771 insertions, 4684 deletions
diff --git a/Game/Code/Classes/UAudioDecoder_FFMpeg.pas b/Game/Code/Classes/UAudioDecoder_FFMpeg.pas index c705d603..646e9eef 100644 --- a/Game/Code/Classes/UAudioDecoder_FFMpeg.pas +++ b/Game/Code/Classes/UAudioDecoder_FFMpeg.pas @@ -17,36 +17,33 @@ interface {$MODE Delphi} {$ENDIF} -{$I switches.inc} - - -uses Classes, - {$IFDEF win32} - windows, - {$ENDIF} - SysUtils, - SDL, - avcodec, // FFMpeg Audio file decoding - avformat, - avutil, - avio, // used for url_ferror - mathematics, // used for av_rescale_q - ULog, - UMusic; +{$I ../switches.inc} + + +uses + Classes, + {$IFDEF win32} + windows, + {$ENDIF} + SysUtils, + UMusic; implementation uses - {$IFDEF LAZARUS} - lclintf, - {$ifndef win32} - libc, - {$endif} - {$ENDIF} - UIni, - UMain, - UThemes, - UConfig; + {$ifndef win32} + libc, + {$endif} + UIni, + UMain, + avcodec, // FFMpeg Audio file decoding + avformat, + avutil, + avio, // used for url_ferror + mathematics, // used for av_rescale_q + SDL, + ULog, + UConfig; type @@ -106,12 +103,12 @@ type ffmpegStreamIndex : Integer; ffmpegStream : PAVStream; - // "static" vars for DecodeFrame + // state-vars for DecodeFrame pkt : TAVPacket; audio_pkt_data : PChar; audio_pkt_size : integer; - // "static" vars for AudioCallback + // state-vars for AudioCallback audio_buf_index : cardinal; audio_buf_size : cardinal; audio_buf : TAudioBuffer; @@ -127,8 +124,7 @@ type procedure Close(); override; function GetLength(): real; override; - function GetChannelCount(): cardinal; override; - function GetSampleRate(): cardinal; override; + function GetAudioFormatInfo(): TAudioFormatInfo; override; function GetPosition: real; override; procedure SetPosition(Time: real); override; function IsEOF(): boolean; override; @@ -169,7 +165,7 @@ begin audio_buf_index := 0; audio_buf_size := 0; - FillChar(pkt, sizeof(TAVPacket), #0); + FillChar(pkt, sizeof(TAVPacket), 0); Self.pFormatCtx := pFormatCtx; Self.pCodecCtx := pCodecCtx; @@ -221,14 +217,12 @@ begin result := pFormatCtx^.duration / AV_TIME_BASE; end; -function TFFMpegDecodeStream.GetChannelCount(): cardinal; -begin - result := pCodecCtx^.channels; -end; - -function TFFMpegDecodeStream.GetSampleRate(): cardinal; +function TFFMpegDecodeStream.GetAudioFormatInfo(): TAudioFormatInfo; begin - result := pCodecCtx^.sample_rate; + result.Channels := pCodecCtx^.channels; + result.SampleRate := pCodecCtx^.sample_rate; + //result.Format := pCodecCtx^.sample_fmt; // sample_fmt not yet used by FFMpeg + result.Format := asfS16; // use FFMpeg's standard format end; function TFFMpegDecodeStream.IsEOF(): boolean; @@ -260,7 +254,7 @@ begin SDL_mutexP(lock); seekPos := Trunc(Time * AV_TIME_BASE); // FIXME: seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0 - seekFlags := 0; + seekFlags := 0;//AVSEEK_FLAG_BACKWARD; seekRequest := true; SDL_CondSignal(resumeCond); SDL_mutexV(lock); @@ -279,9 +273,9 @@ begin while (true) do begin + //SafeWriteLn('Hallo'); SDL_mutexP(stream.lock); - // wait if end-of-file reached if (eofState) then begin @@ -309,18 +303,19 @@ begin // TODO: Do we need this? // The position is converted to AV_TIME_BASE and then to the stream-specific base. // Why not convert to the stream-specific one from the beginning. - seekTarget := av_rescale_q(stream.seekPos, AV_TIME_BASE_Q, stream.ffmpegStream^.time_base);
- if(av_seek_frame(stream.pFormatCtx, stream.ffmpegStreamIndex,
- seekTarget, stream.seekFlags) = 0) then
- begin
- Log.LogStatus(stream.pFormatCtx^.filename + ': error while seeking', 'UAudioDecoder_FFMpeg');
- end
- else
- begin
- stream.packetQueue.Flush();
- stream.packetQueue.Put(@FlushPacket);
- end;
- stream.seekRequest := false;
+ seekTarget := av_rescale_q(stream.seekPos, AV_TIME_BASE_Q, stream.ffmpegStream^.time_base); + if(av_seek_frame(stream.pFormatCtx, stream.ffmpegStreamIndex, + seekTarget, stream.seekFlags) < 0) then + begin + // this will crash in FPC due to a bug + //Log.LogStatus({stream.pFormatCtx^.filename +} ': error while seeking', 'UAudioDecoder_FFMpeg'); + end + else + begin + stream.packetQueue.Flush(); + stream.packetQueue.Put(@FlushPacket); + end; + stream.seekRequest := false; end; SDL_mutexV(stream.lock); @@ -340,8 +335,10 @@ begin {$ELSE} pbIOCtx := @stream.pFormatCtx^.pb; {$IFEND} + if(url_feof(pbIOCtx) <> 0) then begin + SafeWriteLn('feof'); eofState := true; continue; end; @@ -349,24 +346,25 @@ begin // check for errors if(url_ferror(pbIOCtx) = 0) then begin + SafeWriteLn('Errorf'); // no error -> wait for user input - SDL_Delay(100);
- continue;
- end
- else
- begin
- // an error occured -> abort
- // TODO: eof or quit?
- eofState := true;
- continue;
- end;
- end;
- - //writeln( 'ffmpeg - av_read_frame' ); + SDL_Delay(100); + continue; + end + else + begin + // an error occured -> abort + // TODO: eof or quit? + eofState := true; + continue; + end; + end; + + //SafeWriteLn( 'ffmpeg - av_read_frame' ); if(packet.stream_index = stream.ffmpegStreamIndex) then begin - //writeln( 'packet_queue_put' ); + //SafeWriteLn( 'packet_queue_put' ); stream.packetQueue.put(@packet); end else @@ -375,7 +373,7 @@ begin end; end; - //Writeln('Done: ' + inttostr(stream.packetQueue.nbPackets)); + SafeWriteLn('Done: ' + inttostr(stream.packetQueue.nbPackets)); result := 0; end; @@ -394,21 +392,25 @@ begin begin while (audio_pkt_size > 0) do begin - //writeln( 'got audio packet' ); + //SafeWriteLn( 'got audio packet' ); data_size := bufSize; - // TODO: should be avcodec_decode_audio2 but this wont link on my ubuntu box. + {$IF LIBAVCODEC_VERSION >= 51030000} // 51.30.0 + len1 := avcodec_decode_audio2(pCodecCtx, @buffer, + data_size, audio_pkt_data, audio_pkt_size); + {$ELSE} // FIXME: with avcodec_decode_audio a package could contain several frames // this is not handled yet len1 := avcodec_decode_audio(pCodecCtx, @buffer, data_size, audio_pkt_data, audio_pkt_size); + {$IFEND} - //writeln('avcodec_decode_audio : ' + inttostr( len1 )); + //SafeWriteLn('avcodec_decode_audio : ' + inttostr( len1 )); if(len1 < 0) then begin - // if error, skip frame - //writeln( 'Skip audio frame' ); + // if error, skip frame + SafeWriteLn( 'Skip audio frame' ); audio_pkt_size := 0; break; end; @@ -444,6 +446,7 @@ begin if (audio_pkt_data = PChar(FlushPacket.data)) then begin avcodec_flush_buffers(pCodecCtx); + SafeWriteLn('Flush'); continue; end; @@ -452,11 +455,12 @@ begin begin // end-of-file reached -> set EOF-flag SetEOF(true); + SafeWriteLn('EOF'); // note: buffer is not (even partially) filled -> no data to return exit; end; - //writeln( 'Audio Packet Size - ' + inttostr(audio_pkt_size) ); + //SafeWriteLn( 'Audio Packet Size - ' + inttostr(audio_pkt_size) ); end; end; @@ -480,14 +484,14 @@ begin begin // We have already sent all our data; get more audio_size := DecodeFrame(audio_buf, sizeof(TAudioBuffer)); - //writeln('audio_decode_frame : '+ inttostr(audio_size)); + //SafeWriteLn('audio_decode_frame : '+ inttostr(audio_size)); if(audio_size < 0) then begin // If error, output silence audio_buf_size := 1024; FillChar(audio_buf, audio_buf_size, #0); - //writeln( 'Silence' ); + //SafeWriteLn( 'Silence' ); end else begin @@ -531,11 +535,11 @@ begin // init end-of-file package av_init_packet(EOFPacket); - EOFPacket.data := Pointer(PChar('EOF'));
+ EOFPacket.data := Pointer(PChar('EOF')); // init flush package av_init_packet(FlushPacket); - FlushPacket.data := Pointer(PChar('FLUSH'));
+ FlushPacket.data := Pointer(PChar('FLUSH')); result := true; end; @@ -611,7 +615,7 @@ begin end; avcodec_open(pCodecCtx, pCodec); - //writeln( 'Opened the codec' ); + //WriteLn( 'Opened the codec' ); stream := TFFMpegDecodeStream.Create(pFormatCtx, pCodecCtx, pCodec, ffmpegStreamID, ffmpegStream); @@ -671,7 +675,7 @@ begin Self.lastPkt := pkt1; inc(Self.nbPackets); - //Writeln('Put: ' + inttostr(nbPackets)); + //SafeWriteLn('Put: ' + inttostr(nbPackets)); Self.size := Self.size + pkt1^.pkt.size; SDL_CondSignal(Self.cond); @@ -705,7 +709,7 @@ begin Self.lastPkt := nil; dec(Self.nbPackets); - //Writeln('Get: ' + inttostr(nbPackets)); + //SafeWriteLn('Get: ' + inttostr(nbPackets)); Self.size := Self.size - pkt1^.pkt.size; pkt := pkt1^.pkt; @@ -734,22 +738,23 @@ procedure TPacketQueue.Flush(); var pkt, pkt1: PAVPacketList; begin - SDL_LockMutex(Self.mutex);
-
- pkt := Self.firstPkt;
- while(pkt <> nil) do
- begin
- pkt1 := pkt^.next;
- av_free_packet(@pkt^.pkt);
- av_freep(pkt);
- pkt := pkt1;
- end;
- Self.lastPkt := nil;
- Self.firstPkt := nil;
- Self.nbPackets := 0;
- Self.size := 0;
-
- SDL_UnlockMutex(Self.mutex);
+ SDL_LockMutex(Self.mutex); + + pkt := Self.firstPkt; + while(pkt <> nil) do + begin + pkt1 := pkt^.next; + av_free_packet(@pkt^.pkt); + // Note: param must be a pointer to a pointer! + av_freep(@pkt); + pkt := pkt1; + end; + Self.lastPkt := nil; + Self.firstPkt := nil; + Self.nbPackets := 0; + Self.size := 0; + + SDL_UnlockMutex(Self.mutex); end; diff --git a/Game/Code/Classes/UAudioInput_Bass.pas b/Game/Code/Classes/UAudioInput_Bass.pas index 75a5aee5..6d661258 100644 --- a/Game/Code/Classes/UAudioInput_Bass.pas +++ b/Game/Code/Classes/UAudioInput_Bass.pas @@ -1,287 +1,203 @@ -unit UAudioInput_Bass; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - - -uses Classes, - {$IFDEF win32} - windows, - {$ENDIF} - SysUtils, - bass, - ULog, - UMusic; - -implementation - -uses - {$IFDEF LAZARUS} - lclintf, - {$ENDIF} - URecord, - UIni, - UMain, - UCommon, - UThemes; - -type - TAudioInput_Bass = class( TInterfacedObject, IAudioInput) - private - public - function GetName: String; - - {IAudioInput interface} - procedure InitializeRecord; - - procedure CaptureStart; - procedure CaptureStop; - procedure CaptureCard(Card: byte; CaptureSoundLeft, CaptureSoundRight: TSound); - procedure StopCard(Card: byte); - end; - - TBassSoundCard = class(TGenericSoundCard) - RecordStream: HSTREAM; - end; - -var - singleton_AudioInputBass : IAudioInput; - - -function TAudioInput_Bass.GetName: String; -begin - result := 'BASS_Input'; -end; - -procedure TAudioInput_Bass.InitializeRecord; -var - device: integer; - Descr: string; - input: integer; - input2: integer; - InputName: PChar; - Flags: integer; - mic: array[0..15] of integer; - SC: integer; // soundcard - SCI: integer; // soundcard input - No: integer; - -function isDuplicate(Desc: String): Boolean; -var - I: Integer; -begin - Result := False; - //Check for Soundcard with same Description - For I := 0 to SC-1 do - begin - if (AudioInputProcessor.SoundCard[I].Description = Desc) then - begin - Result := True; - Break; - end; - end; -end; - -begin - with AudioInputProcessor do - begin - // checks for recording devices and puts them into an array - SetLength(SoundCard, 0); - - SC := 0; - Descr := BASS_RecordGetDeviceDescription(SC); - - while (Descr <> '') do - begin - //If there is another SoundCard with the Same ID, Search an available Name - if (IsDuplicate(Descr)) then - begin - No:= 1; //Count of SoundCards with same Name - Repeat - Inc(No) - Until not IsDuplicate(Descr + ' (' + InttoStr(No) + ')'); - - //Set Description - Descr := Descr + ' (' + InttoStr(No) + ')'; - end; - - SetLength(SoundCard, SC+1); - - // TODO: free object on termination - SoundCard[SC] := TBassSoundCard.Create(); - SoundCard[SC].Description := Descr; - - //Get Recording Inputs - SCI := 0; - BASS_RecordInit(SC); - - InputName := BASS_RecordGetInputName(SCI); - - {$IFDEF DARWIN} - // Under MacOSX the SingStar Mics have an empty - // InputName. So, we have to add a hard coded - // Workaround for this problem - if (InputName = nil) and (Pos( 'USBMIC Serial#', Descr) > 0) then - begin - InputName := 'Microphone'; - end; - {$ENDIF} - - SetLength(SoundCard[SC].Input, 1); - SoundCard[SC].Input[SCI].Name := InputName; - - // process each input - while (InputName <> nil) do - begin - Flags := BASS_RecordGetInput(SCI); - if (SCI >= 1) {AND (Flags AND BASS_INPUT_OFF = 0)} then - begin - SetLength(SoundCard[SC].Input, SCI+1); - SoundCard[SC].Input[SCI].Name := InputName; - end; - - //Set Mic Index - if ((Flags and BASS_INPUT_TYPE_MIC) = 1) then - SoundCard[SC].MicInput := SCI; - - Inc(SCI); - InputName := BASS_RecordGetInputName(SCI); - end; - - BASS_RecordFree; - - Inc(SC); - Descr := BASS_RecordGetDeviceDescription(SC); - end; // while - end; // with Recording -end; - -// TODO: code is used by all IAudioInput implementors -// -> move to a common superclass (TAudioInput_Generic?) -procedure TAudioInput_Bass.CaptureStart; -var - S: integer; - SC: integer; - PlayerLeft, PlayerRight: integer; - CaptureSoundLeft, CaptureSoundRight: TSound; -begin - for S := 0 to High(AudioInputProcessor.Sound) do - AudioInputProcessor.Sound[S].BufferLong[0].Clear; - - for SC := 0 to High(Ini.CardList) do - begin - PlayerLeft := Ini.CardList[SC].ChannelL-1; - PlayerRight := Ini.CardList[SC].ChannelR-1; - if PlayerLeft >= PlayersPlay then PlayerLeft := -1; - if PlayerRight >= PlayersPlay then PlayerRight := -1; - if (PlayerLeft > -1) or (PlayerRight > -1) then begin - if (PlayerLeft > -1) then - CaptureSoundLeft := AudioInputProcessor.Sound[PlayerLeft] - else - CaptureSoundLeft := nil; - if (PlayerRight > -1) then - CaptureSoundRight := AudioInputProcessor.Sound[PlayerRight] - else - CaptureSoundRight := nil; - - CaptureCard(SC, CaptureSoundLeft, CaptureSoundRight); - end; - end; -end; - -// TODO: code is used by all IAudioInput implementors -// -> move to a common superclass (TAudioInput_Generic?) -procedure TAudioInput_Bass.CaptureStop; -var - SC: integer; - PlayerLeft: integer; - PlayerRight: integer; -begin - - for SC := 0 to High(Ini.CardList) do begin - PlayerLeft := Ini.CardList[SC].ChannelL-1; - PlayerRight := Ini.CardList[SC].ChannelR-1; - if PlayerLeft >= PlayersPlay then PlayerLeft := -1; - if PlayerRight >= PlayersPlay then PlayerRight := -1; - if (PlayerLeft > -1) or (PlayerRight > -1) then - StopCard(SC); - end; - -end; - -{* - * Bass input capture callback. - * Params: - * stream - BASS input stream - * buffer - buffer of captured samples - * len - size of buffer in bytes - * user - players associated with left/right channels - *} -function MicrophoneCallback(stream: HSTREAM; buffer: Pointer; - len: Cardinal; Card: Cardinal): boolean; stdcall; -begin - AudioInputProcessor.HandleMicrophoneData(buffer, len, AudioInputProcessor.SoundCard[Card]); - Result := true; -end; - -{* - * Start input-capturing on Soundcard specified by Card. - * Params: - * Card - soundcard index in AudioInputProcessor.SoundCard array - * CaptureSoundLeft - sound(-buffer) used for left channel capture data - * CaptureSoundRight - sound(-buffer) used for right channel capture data - *} -procedure TAudioInput_Bass.CaptureCard(Card: byte; CaptureSoundLeft, CaptureSoundRight: TSound); -var - Error: integer; - ErrorMsg: string; - bassSoundCard: TBassSoundCard; -begin - if not BASS_RecordInit(Card) then - begin - Error := BASS_ErrorGetCode; - ErrorMsg := IntToStr(Error); - if Error = BASS_ERROR_DX then ErrorMsg := 'No DX5'; - if Error = BASS_ERROR_ALREADY then ErrorMsg := 'The device has already been initialized'; - if Error = BASS_ERROR_DEVICE then ErrorMsg := 'The device number specified is invalid'; - if Error = BASS_ERROR_DRIVER then ErrorMsg := 'There is no available device driver'; - Log.LogError('Error initializing record [' + IntToStr(Card) + ']'); - Log.LogError('TAudio_bass.CaptureCard: Error initializing record: ' + ErrorMsg); - end - else - begin - bassSoundCard := TBassSoundCard(AudioInputProcessor.SoundCard[Card]); - bassSoundCard.CaptureSoundLeft := CaptureSoundLeft; - bassSoundCard.CaptureSoundRight := CaptureSoundRight; - - // capture in 44.1kHz/stereo/16bit and a 20ms callback period - bassSoundCard.RecordStream := - BASS_RecordStart(44100, 2, MakeLong(0, 20) , @MicrophoneCallback, Card); - end; -end; - -{* - * Stop input-capturing on Soundcard specified by Card. - * Params: - * Card - soundcard index in AudioInputProcessor.SoundCard array - *} -procedure TAudioInput_Bass.StopCard(Card: byte); -begin - BASS_RecordSetDevice(Card); - BASS_RecordFree; -end; - - -initialization - singleton_AudioInputBass := TAudioInput_Bass.create(); - AudioManager.add( singleton_AudioInputBass ); - -finalization - AudioManager.Remove( singleton_AudioInputBass ); - -end. +unit UAudioInput_Bass;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ Classes,
+ SysUtils,
+ URecord,
+ UMusic;
+
+implementation
+
+uses
+ UMain,
+ UIni,
+ ULog,
+ UAudioCore_Bass,
+ Windows,
+ bass;
+
+type
+ TAudioInput_Bass = class(TAudioInputBase)
+ public
+ function GetName: String; override;
+ function InitializeRecord: boolean; override;
+ destructor Destroy; override;
+ end;
+
+ TBassInputDevice = class(TAudioInputDevice)
+ public
+ DeviceIndex: integer; // index in TAudioInputProcessor.Device[]
+ BassDeviceID: integer; // DeviceID used by BASS
+ RecordStream: HSTREAM;
+
+ procedure Start(); override;
+ procedure Stop(); override;
+ end;
+
+var
+ singleton_AudioInputBass : IAudioInput;
+
+
+{ Global }
+
+{*
+ * Bass input capture callback.
+ * Params:
+ * stream - BASS input stream
+ * buffer - buffer of captured samples
+ * len - size of buffer in bytes
+ * user - players associated with left/right channels
+ *}
+function MicrophoneCallback(stream: HSTREAM; buffer: Pointer;
+ len: Cardinal; Card: Cardinal): boolean; stdcall;
+begin
+ AudioInputProcessor.HandleMicrophoneData(buffer, len,
+ AudioInputProcessor.Device[Card]);
+ Result := true;
+end;
+
+
+{ TBassInputDevice }
+
+{*
+ * Start input-capturing on this device.
+ * TODO: call BASS_RecordInit only once
+ *}
+procedure TBassInputDevice.Start();
+const
+ captureFreq = 44100;
+begin
+ // recording already started -> stop first
+ if (RecordStream <> 0) then
+ Stop();
+
+ // TODO: Call once. Otherwise it's to slow
+ if not BASS_RecordInit(BassDeviceID) then
+ begin
+ Log.LogError('TBassInputDevice.Start: Error initializing device['+IntToStr(DeviceIndex)+']: ' +
+ TAudioCore_Bass.ErrorGetString());
+ Exit;
+ end;
+
+ SampleRate := captureFreq;
+
+ // capture in 44.1kHz/stereo/16bit and a 20ms callback period
+ RecordStream := BASS_RecordStart(captureFreq, 2, MakeLong(0, 20),
+ @MicrophoneCallback, DeviceIndex);
+ if (RecordStream = 0) then
+ begin
+ BASS_RecordFree;
+ Exit;
+ end;
+end;
+
+{*
+ * Stop input-capturing on this device.
+ *}
+procedure TBassInputDevice.Stop();
+begin
+ if (RecordStream = 0) then
+ Exit;
+ // TODO: Don't free the device. Do this on close
+ if (BASS_RecordSetDevice(BassDeviceID)) then
+ BASS_RecordFree;
+ RecordStream := 0;
+end;
+
+
+{ TAudioInput_Bass }
+
+function TAudioInput_Bass.GetName: String;
+begin
+ result := 'BASS_Input';
+end;
+
+function TAudioInput_Bass.InitializeRecord(): boolean;
+var
+ Descr: PChar;
+ SourceName: PChar;
+ Flags: integer;
+ BassDeviceID: integer;
+ BassDevice: TBassInputDevice;
+ DeviceIndex: integer;
+ SourceIndex: integer;
+begin
+ result := false;
+
+ DeviceIndex := 0;
+ BassDeviceID := 0;
+ SetLength(AudioInputProcessor.Device, 0);
+
+ // checks for recording devices and puts them into an array
+ while true do
+ begin
+ Descr := BASS_RecordGetDeviceDescription(BassDeviceID);
+ if (Descr = nil) then
+ break;
+
+ SetLength(AudioInputProcessor.Device, DeviceIndex+1);
+
+ // TODO: free object on termination
+ BassDevice := TBassInputDevice.Create();
+ AudioInputProcessor.Device[DeviceIndex] := BassDevice;
+
+ BassDevice.DeviceIndex := DeviceIndex;
+ BassDevice.BassDeviceID := BassDeviceID;
+ BassDevice.Description := UnifyDeviceName(Descr, DeviceIndex);
+
+ // get input sources
+ SourceIndex := 0;
+ BASS_RecordInit(BassDeviceID);
+ BassDevice.MicInput := 0;
+
+ // process each input
+ while true do
+ begin
+ SourceName := BASS_RecordGetInputName(SourceIndex);
+ if (SourceName = nil) then
+ break;
+
+ SetLength(BassDevice.Source, SourceIndex+1);
+ BassDevice.Source[SourceIndex].Name :=
+ UnifyDeviceSourceName(SourceName, BassDevice.Description);
+
+ // set mic index
+ Flags := BASS_RecordGetInput(SourceIndex);
+ if ((Flags and BASS_INPUT_TYPE_MIC) <> 0) then
+ BassDevice.MicInput := SourceIndex;
+
+ Inc(SourceIndex);
+ end;
+
+ BASS_RecordFree;
+
+ Inc(DeviceIndex);
+ Inc(BassDeviceID);
+ end;
+
+ result := true;
+end;
+
+destructor TAudioInput_Bass.Destroy;
+begin
+ inherited;
+end;
+
+
+initialization
+ singleton_AudioInputBass := TAudioInput_Bass.create();
+ AudioManager.add( singleton_AudioInputBass );
+
+finalization
+ AudioManager.Remove( singleton_AudioInputBass );
+
+end.
diff --git a/Game/Code/Classes/UAudioInput_Portaudio.pas b/Game/Code/Classes/UAudioInput_Portaudio.pas index 8073a7f3..c969a1b3 100644 --- a/Game/Code/Classes/UAudioInput_Portaudio.pas +++ b/Game/Code/Classes/UAudioInput_Portaudio.pas @@ -6,60 +6,43 @@ interface {$MODE Delphi} {$ENDIF} -{$I switches.inc} +{$I ../switches.inc} -uses Classes, - SysUtils, - portaudio, - {$IFDEF UsePortmixer} - portmixer, - {$ENDIF} - ULog, - UMusic; +uses + Classes, + SysUtils, + UMusic; implementation uses - {$IFDEF LAZARUS} - lclintf, - {$ENDIF} - URecord, - UIni, - UMain, - UCommon, - UThemes; -{ -type - TPaHostApiIndex = PaHostApiIndex; - TPaDeviceIndex = PaDeviceIndex; - PPaStream = ^PaStreamPtr; - PPaStreamCallbackTimeInfo = ^PaStreamCallbackTimeInfo; - TPaStreamCallbackFlags = PaStreamCallbackFlags; - TPaHostApiTypeId = PaHostApiTypeId; - PPaHostApiInfo = ^PaHostApiInfo; - PPaDeviceInfo = ^PaDeviceInfo; - TPaError = PaError; - TPaStreamParameters = PaStreamParameters; -} + URecord, + UIni, + ULog, + UMain, + {$IFDEF UsePortmixer} + portmixer, + {$ENDIF} + portaudio; + type - TAudioInput_Portaudio = class( TInterfacedObject, IAudioInput ) + TAudioInput_Portaudio = class(TAudioInputBase) private function GetPreferredApiIndex(): TPaHostApiIndex; public - function GetName: String; - procedure InitializeRecord; - - procedure CaptureStart; - procedure CaptureStop; - - procedure CaptureCard(Card: byte; CaptureSoundLeft, CaptureSoundRight: TSound); - procedure StopCard(Card: byte); + function GetName: String; override; + function InitializeRecord: boolean; override; + destructor Destroy; override; end; - TPortaudioSoundCard = class(TGenericSoundCard) - RecordStream: PPaStream; - DeviceIndex: TPaDeviceIndex; + TPortaudioInputDevice = class(TAudioInputDevice) + public + RecordStream: PPaStream; + PaDeviceIndex: TPaDeviceIndex; + + procedure Start(); override; + procedure Stop(); override; end; function MicrophoneCallback(input: Pointer; output: Pointer; frameCount: Longword; @@ -69,9 +52,6 @@ function MicrophoneCallback(input: Pointer; output: Pointer; frameCount: Longwor var singleton_AudioInputPortaudio : IAudioInput; -const - sampleRate: Double = 44100.; - {* the default API used by Portaudio is the least common denominator * and might lack efficiency. ApiPreferenceOrder defines the order of * preferred APIs to use. The first API-type in the list is tried first. If it's @@ -102,6 +82,62 @@ var array[0..0] of TPaHostApiTypeId = ( paDefaultApi ); {$IFEND} + +{ TPortaudioInputDevice } + +procedure TPortaudioInputDevice.Start(); +var + Error: TPaError; + ErrorMsg: string; + inputParams: TPaStreamParameters; + deviceInfo: PPaDeviceInfo; +begin + // get input latency info + deviceInfo := Pa_GetDeviceInfo(PaDeviceIndex); + + // set input stream parameters + with inputParams do begin + device := PaDeviceIndex; + channelCount := 2; + sampleFormat := paInt16; + suggestedLatency := deviceInfo^.defaultLowInputLatency; + hostApiSpecificStreamInfo := nil; + end; + + Log.LogStatus(inttostr(PaDeviceIndex), 'Portaudio'); + Log.LogStatus(floattostr(deviceInfo^.defaultLowInputLatency), 'Portaudio'); + + // open input stream + Error := Pa_OpenStream(RecordStream, @inputParams, nil, SampleRate, + paFramesPerBufferUnspecified, paNoFlag, + @MicrophoneCallback, Pointer(Self)); + if(Error <> paNoError) then begin + ErrorMsg := Pa_GetErrorText(Error); + Log.CriticalError('TPortaudioInputDevice.Start(): Error opening stream: ' + ErrorMsg); + //Halt; + end; + + // start capture + Error := Pa_StartStream(RecordStream); + if(Error <> paNoError) then begin + Pa_CloseStream(RecordStream); + ErrorMsg := Pa_GetErrorText(Error); + Log.CriticalError('TPortaudioInputDevice.Start(): Error starting stream: ' + ErrorMsg); + //Halt; + end; +end; + +procedure TPortaudioInputDevice.Stop(); +begin + if assigned(RecordStream) then begin + Pa_StopStream(RecordStream); + Pa_CloseStream(RecordStream); + end; +end; + + +{ TAudioInput_Portaudio } + function TAudioInput_Portaudio.GetName: String; begin result := 'Portaudio'; @@ -130,8 +166,7 @@ begin end; end; -// TODO: should be a function with boolean return type -procedure TAudioInput_Portaudio.InitializeRecord; +function TAudioInput_Portaudio.InitializeRecord(): boolean; var i: integer; apiIndex: TPaHostApiIndex; @@ -139,37 +174,42 @@ var deviceName: string; deviceIndex: TPaDeviceIndex; deviceInfo: PPaDeviceInfo; - inputCnt: integer; - inputName: string; + sourceCnt: integer; + sourceName: string; SC: integer; // soundcard - SCI: integer; // soundcard input + SCI: integer; // soundcard source err: TPaError; errMsg: string; - paSoundCard: TPortaudioSoundCard; + paDevice: TPortaudioInputDevice; inputParams: TPaStreamParameters; stream: PPaStream; {$IFDEF UsePortmixer} mixer: PPxMixer; {$ENDIF} +const + captureFreq = 44100; begin - // TODO: call Pa_Terminate() on termination + result := false; + + writeln('0'); + err := Pa_Initialize(); if(err <> paNoError) then begin - Log.CriticalError('Portaudio.InitializeRecord: ' + Pa_GetErrorText(err)); - //Log.LogError('Portaudio.InitializeRecord: ' + Pa_GetErrorText(err)); - // result := false; + Log.LogError('Portaudio.InitializeRecord: ' + Pa_GetErrorText(err)); Exit; end; - + writeln('1'); apiIndex := GetPreferredApiIndex(); apiInfo := Pa_GetHostApiInfo(apiIndex); SC := 0; + writeln('2'); // init array-size to max. input-devices count - SetLength(AudioInputProcessor.SoundCard, apiInfo^.deviceCount); // fix deviceCountL - for i:= 0 to High(AudioInputProcessor.SoundCard) do + SetLength(AudioInputProcessor.Device, apiInfo^.deviceCount); + for i:= 0 to High(AudioInputProcessor.Device) do begin + writeln('25'); // convert API-specific device-index to global index deviceIndex := Pa_HostApiDeviceIndexToDeviceIndex(apiIndex, i); deviceInfo := Pa_GetDeviceInfo(deviceIndex); @@ -178,14 +218,13 @@ begin if(deviceInfo^.maxInputChannels <= 0) then continue; - // TODO: free object on termination - paSoundCard := TPortaudioSoundCard.Create(); - AudioInputProcessor.SoundCard[SC] := paSoundCard; + paDevice := TPortaudioInputDevice.Create(); + AudioInputProcessor.Device[SC] := paDevice; // retrieve device-name deviceName := deviceInfo^.name; - paSoundCard.Description := deviceName; - paSoundCard.DeviceIndex := deviceIndex; + paDevice.Description := deviceName; + paDevice.PaDeviceIndex := deviceIndex; // setup desired input parameters with inputParams do begin @@ -196,29 +235,32 @@ begin hostApiSpecificStreamInfo := nil; end; + paDevice.SampleRate := captureFreq; + // check if device supports our input-format - err := Pa_IsFormatSupported(@inputParams, nil, sampleRate); + err := Pa_IsFormatSupported(@inputParams, nil, paDevice.SampleRate); if(err <> 0) then begin // format not supported -> skip errMsg := Pa_GetErrorText(err); Log.LogError('Portaudio.InitializeRecord, device: "'+ deviceName +'" ' + '('+ errMsg +')'); - paSoundCard.Free(); + paDevice.Free(); continue; end; // TODO: retry with mono if stereo is not supported // TODO: retry with input-latency set to 20ms (defaultLowInputLatency might // not be set correctly in OSS) + // use TPaDeviceInfo.defaultSampleRate - err := Pa_OpenStream(stream, @inputParams, nil, sampleRate, + err := Pa_OpenStream(stream, @inputParams, nil, paDevice.SampleRate, paFramesPerBufferUnspecified, paNoFlag, @MicrophoneCallback, nil); if(err <> paNoError) then begin // unable to open device -> skip errMsg := Pa_GetErrorText(err); Log.LogError('Portaudio.InitializeRecord, device: "'+ deviceName +'" ' + '('+ errMsg +')'); - paSoundCard.Free(); + paDevice.Free(); continue; end; @@ -229,14 +271,14 @@ begin mixer := Px_OpenMixer(stream, 0); // get input count - inputCnt := Px_GetNumInputSources(mixer); - SetLength(paSoundCard.Input, inputCnt); + sourceCnt := Px_GetNumInputSources(mixer); + SetLength(paDevice.Source, sourceCnt); // get input names - for SCI := 0 to inputCnt-1 do + for SCI := 0 to sourceCnt-1 do begin - inputName := Px_GetInputSourceName(mixer, SCI); - paSoundCard.Input[SCI].Name := inputName; + sourceName := Px_GetInputSourceName(mixer, SCI); + paDevice.Source[SCI].Name := sourceName; end; Px_CloseMixer(mixer); @@ -247,80 +289,46 @@ begin // TODO: check if callback was called (this problem may occur on some devices) //Pa_StopStream(stream); - Pa_CloseStream(stream); - // create a standard input source - SetLength(paSoundCard.Input, 1); - paSoundCard.Input[0].Name := 'Standard'; + SetLength(paDevice.Source, 1); + paDevice.Source[0].Name := 'Standard'; {$ENDIF} + // close test-stream + Pa_CloseStream(stream); + // use default input source - paSoundCard.InputSelected := 0; + paDevice.SourceSelected := 0; Inc(SC); end; + writeln('3'); // adjust size to actual input-device count - SetLength(AudioInputProcessor.SoundCard, SC); + SetLength(AudioInputProcessor.Device, SC); Log.LogStatus('#Soundcards: ' + inttostr(SC), 'Portaudio'); { SoundCard[SC].InputSelected := Mic[Device]; } + result := true; end; -// TODO: code is used by all IAudioInput implementors -// -> move to a common superclass (TAudioInput_Generic?) -procedure TAudioInput_Portaudio.CaptureStart; -var - S: integer; - SC: integer; - PlayerLeft, PlayerRight: integer; - CaptureSoundLeft, CaptureSoundRight: TSound; -begin - for S := 0 to High(AudioInputProcessor.Sound) do - AudioInputProcessor.Sound[S].BufferLong[0].Clear; - - for SC := 0 to High(Ini.CardList) do begin - PlayerLeft := Ini.CardList[SC].ChannelL-1; - PlayerRight := Ini.CardList[SC].ChannelR-1; - if PlayerLeft >= PlayersPlay then PlayerLeft := -1; - if PlayerRight >= PlayersPlay then PlayerRight := -1; - if (PlayerLeft > -1) or (PlayerRight > -1) then begin - if (PlayerLeft > -1) then - CaptureSoundLeft := AudioInputProcessor.Sound[PlayerLeft] - else - CaptureSoundLeft := nil; - if (PlayerRight > -1) then - CaptureSoundRight := AudioInputProcessor.Sound[PlayerRight] - else - CaptureSoundRight := nil; - - CaptureCard(SC, CaptureSoundLeft, CaptureSoundRight); - end; - end; -end; - -// TODO: code is used by all IAudioInput implementors -// -> move to a common superclass (TAudioInput_Generic?) -procedure TAudioInput_Portaudio.CaptureStop; +destructor TAudioInput_Portaudio.Destroy; var - SC: integer; - PlayerLeft: integer; - PlayerRight: integer; + i: integer; + paSoundCard: TPortaudioInputDevice; begin - - for SC := 0 to High(Ini.CardList) do begin - PlayerLeft := Ini.CardList[SC].ChannelL-1; - PlayerRight := Ini.CardList[SC].ChannelR-1; - if PlayerLeft >= PlayersPlay then PlayerLeft := -1; - if PlayerRight >= PlayersPlay then PlayerRight := -1; - if (PlayerLeft > -1) or (PlayerRight > -1) then - StopCard(SC); + Pa_Terminate(); + for i := 0 to High(AudioInputProcessor.Device) do + begin + AudioInputProcessor.Device[i].Free(); end; + AudioInputProcessor.Device := nil; + inherited Destroy; end; {* @@ -334,81 +342,6 @@ begin result := paContinue; end; -{* - * Start input-capturing on Soundcard specified by Card. - * Params: - * Card - soundcard index in Recording.SoundCard array - * CaptureSoundLeft - sound(-buffer) used for left channel capture data - * CaptureSoundRight - sound(-buffer) used for right channel capture data - *} -procedure TAudioInput_Portaudio.CaptureCard(Card: byte; CaptureSoundLeft, CaptureSoundRight: TSound); -var - Error: TPaError; - ErrorMsg: string; - inputParams: TPaStreamParameters; - deviceInfo: PPaDeviceInfo; - stream: PPaStream; - paSoundCard: TPortaudioSoundCard; -begin - paSoundCard := TPortaudioSoundCard(AudioInputProcessor.SoundCard[Card]); - paSoundCard.CaptureSoundLeft := CaptureSoundLeft; - paSoundCard.CaptureSoundRight := CaptureSoundRight; - - // get input latency info - deviceInfo := Pa_GetDeviceInfo(paSoundCard.DeviceIndex); - - // set input stream parameters - with inputParams do begin - device := paSoundCard.DeviceIndex; - channelCount := 2; - sampleFormat := paInt16; - suggestedLatency := deviceInfo^.defaultLowInputLatency; - hostApiSpecificStreamInfo := nil; - end; - - Log.LogStatus(inttostr(paSoundCard.DeviceIndex), 'Portaudio'); - Log.LogStatus(floattostr(deviceInfo^.defaultLowInputLatency), 'Portaudio'); - - // open input stream - Error := Pa_OpenStream(stream, @inputParams, nil, sampleRate, - paFramesPerBufferUnspecified, paNoFlag, - @MicrophoneCallback, Pointer(paSoundCard)); - if(Error <> paNoError) then begin - ErrorMsg := Pa_GetErrorText(Error); - Log.CriticalError('TAudio_Portaudio.CaptureCard('+ IntToStr(Card) +'): Error opening stream: ' + ErrorMsg); - //Halt; - end; - - paSoundCard.RecordStream := stream; - - // start capture - Error := Pa_StartStream(stream); - if(Error <> paNoError) then begin - Pa_CloseStream(stream); - ErrorMsg := Pa_GetErrorText(Error); - Log.CriticalError('TAudio_Portaudio.CaptureCard('+ IntToStr(Card) +'): Error starting stream: ' + ErrorMsg); - //Halt; - end; -end; - -{* - * Stop input-capturing on Soundcard specified by Card. - * Params: - * Card - soundcard index in Recording.SoundCard array - *} -procedure TAudioInput_Portaudio.StopCard(Card: byte); -var - stream: PPaStream; - paSoundCard: TPortaudioSoundCard; -begin - paSoundCard := TPortaudioSoundCard(AudioInputProcessor.SoundCard[Card]); - stream := paSoundCard.RecordStream; - if(stream <> nil) then begin - Pa_StopStream(stream); - Pa_CloseStream(stream); - end; -end; - initialization singleton_AudioInputPortaudio := TAudioInput_Portaudio.create(); diff --git a/Game/Code/Classes/UAudioPlayback_Bass.pas b/Game/Code/Classes/UAudioPlayback_Bass.pas index 87ff183d..266a5ec3 100644 --- a/Game/Code/Classes/UAudioPlayback_Bass.pas +++ b/Game/Code/Classes/UAudioPlayback_Bass.pas @@ -9,35 +9,31 @@ interface {$I switches.inc} -uses Classes, - {$IFDEF win32} - windows, - {$ENDIF} - SysUtils, - bass, - ULog, - UMusic; +uses + Classes, + SysUtils, + UMusic; implementation uses - {$IFDEF LAZARUS} - lclintf, - {$ENDIF} - URecord, - UIni, - UMain, - UCommon, - UThemes; + UIni, + UMain, + ULog, + UAudioCore_Bass, + bass; type - TBassOutputStream = class(TAudioPlaybackStream) + TBassPlaybackStream = class(TAudioPlaybackStream) private Handle: HSTREAM; + Loop: boolean; public constructor Create(); overload; constructor Create(stream: HSTREAM); overload; + procedure Reset(); + procedure Play(); override; procedure Pause(); override; procedure Stop(); override; @@ -46,41 +42,33 @@ type procedure SetLoop(Enabled: boolean); override; function GetLength(): real; override; function GetStatus(): TStreamStatus; override; + function GetVolume(): integer; override; + procedure SetVolume(volume: integer); override; + + function GetPosition: real; + procedure SetPosition(Time: real); + + function IsLoaded(): boolean; end; type TAudioPlayback_Bass = class( TInterfacedObject, IAudioPlayback) private - MusicStream: HSTREAM; - - StartSoundStream: HSTREAM; - BackSoundStream: HSTREAM; - SwooshSoundStream: HSTREAM; - ChangeSoundStream: HSTREAM; - OptionSoundStream: HSTREAM; - ClickSoundStream: HSTREAM; - DrumSoundStream: HSTREAM; - HihatSoundStream: HSTREAM; - ClapSoundStream: HSTREAM; - ShuffleSoundStream: HSTREAM; - - //Custom Sounds - CustomSounds: array of TCustomSoundEntry; - Loaded: boolean; - Loop: boolean; + MusicStream: TBassPlaybackStream; + function Load(Filename: string): TBassPlaybackStream; public function GetName: String; {IAudioOutput interface} - procedure InitializePlayback; + function InitializePlayback(): boolean; procedure SetVolume(Volume: integer); procedure SetMusicVolume(Volume: integer); procedure SetLoop(Enabled: boolean); - function Open(Name: string): boolean; // true if succeed - + function Open(Filename: string): boolean; // true if succeed + procedure Rewind; procedure Play; procedure Pause; //Pause Mod @@ -91,79 +79,106 @@ type function GetPosition: real; procedure SetPosition(Time: real); - procedure PlayStart; - procedure PlayBack; - procedure PlaySwoosh; - procedure PlayChange; - procedure PlayOption; - procedure PlayClick; - procedure PlayDrum; - procedure PlayHihat; - procedure PlayClap; - procedure PlayShuffle; - procedure StopShuffle; - - function LoadSoundFromFile(var stream: HSTREAM; Name: string): boolean; - //Equalizer - function GetFFTData: TFFTData; + procedure GetFFTData(var data: TFFTData); // Interface for Visualizer function GetPCMData(var data: TPCMData): Cardinal; - //Custom Sounds - function LoadCustomSound(const Filename: String): Cardinal; - procedure PlayCustomSound(const Index: Cardinal ); + // Sounds + function OpenSound(const Filename: String): TAudioPlaybackStream; + procedure PlaySound(stream: TAudioPlaybackStream);
+ procedure StopSound(stream: TAudioPlaybackStream); end; var singleton_AudioPlaybackBass : IAudioPlayback; -constructor TBassOutputStream.Create(); +constructor TBassPlaybackStream.Create(); begin inherited; + Reset(); end; -constructor TBassOutputStream.Create(stream: HSTREAM); +constructor TBassPlaybackStream.Create(stream: HSTREAM); begin Create(); Handle := stream; end; -procedure TBassOutputStream.Play(); +procedure TBassPlaybackStream.Reset(); +begin + Loop := false; + if (Handle <> 0) then + Bass_StreamFree(Handle); + Handle := 0; +end; + +procedure TBassPlaybackStream.Play(); begin - BASS_ChannelPlay(Handle, True); + BASS_ChannelPlay(Handle, Loop); end; -procedure TBassOutputStream.Pause(); +procedure TBassPlaybackStream.Pause(); begin - //if (Loaded) then BASS_ChannelPause(Handle); end; -procedure TBassOutputStream.Stop(); +procedure TBassPlaybackStream.Stop(); begin BASS_ChannelStop(Handle); end; -procedure TBassOutputStream.Close(); +procedure TBassPlaybackStream.Close(); begin - Bass_StreamFree(Handle); + Reset(); end; -function TBassOutputStream.GetLoop(): boolean; +function TBassPlaybackStream.GetVolume(): integer; begin - // TODO - result := false; + Result := 0; + BASS_ChannelSetAttributes(Handle, PInteger(nil)^, Result, PInteger(nil)^); +end; + +procedure TBassPlaybackStream.SetVolume(volume: integer); +begin + // clamp volume + if volume < 0 then + volume := 0; + if volume > 100 then + volume := 100; + // set volume + BASS_ChannelSetAttributes(Handle, -1, volume, -101); end; -procedure TBassOutputStream.SetLoop(Enabled: boolean); +function TBassPlaybackStream.GetPosition: real; +var + bytes: integer; +begin + bytes := BASS_ChannelGetPosition(Handle); + Result := BASS_ChannelBytes2Seconds(Handle, bytes); +end; + +procedure TBassPlaybackStream.SetPosition(Time: real); +var + bytes: integer; begin - // TODO + bytes := BASS_ChannelSeconds2Bytes(Handle, Time); + BASS_ChannelSetPosition(Handle, bytes); end; -function TBassOutputStream.GetLength(): real; +function TBassPlaybackStream.GetLoop(): boolean; +begin + result := Loop; +end; + +procedure TBassPlaybackStream.SetLoop(Enabled: boolean); +begin + Loop := Enabled; +end; + +function TBassPlaybackStream.GetLength(): real; var bytes: integer; begin @@ -171,37 +186,45 @@ begin Result := BASS_ChannelBytes2Seconds(Handle, bytes); end; -function TBassOutputStream.GetStatus(): TStreamStatus; +function TBassPlaybackStream.GetStatus(): TStreamStatus; var state: DWORD; begin state := BASS_ChannelIsActive(Handle); case state of BASS_ACTIVE_PLAYING: - result := sPlaying; + result := ssPlaying; BASS_ACTIVE_PAUSED: - result := sPaused; + result := ssPaused; + BASS_ACTIVE_STALLED: + result := ssBlocked; + BASS_ACTIVE_STOPPED: + result := ssStopped; else - result := sStopped; + result := ssUnknown; end; end; +function TBassPlaybackStream.IsLoaded(): boolean; +begin + Result := (Handle <> 0); +end; + function TAudioPlayback_Bass.GetName: String; begin result := 'BASS_Playback'; end; -procedure TAudioPlayback_Bass.InitializePlayback; +function TAudioPlayback_Bass.InitializePlayback(): boolean; var Pet: integer; S: integer; begin -// Log.BenchmarkStart(4); -// Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize'); + result := false; - Loaded := false; - Loop := false; + //Log.BenchmarkStart(4); + //Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize'); if not BASS_Init(1, 44100, 0, 0, nil) then begin @@ -209,30 +232,32 @@ begin Exit; end; -// Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4); + //Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4); // config playing buffer -// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10); -// BASS_SetConfig(BASS_CONFIG_BUFFER, 100); - -// Log.LogStatus('Loading Sounds', 'Music Initialize'); + //BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10); + //BASS_SetConfig(BASS_CONFIG_BUFFER, 100); -// Log.BenchmarkStart(4); - LoadSoundFromFile(StartSoundStream, SoundPath + 'Common Start.mp3'); - LoadSoundFromFile(BackSoundStream, SoundPath + 'Common Back.mp3'); - LoadSoundFromFile(SwooshSoundStream, SoundPath + 'menu swoosh.mp3'); - LoadSoundFromFile(ChangeSoundStream, SoundPath + 'select music change music 50.mp3'); - LoadSoundFromFile(OptionSoundStream, SoundPath + 'option change col.mp3'); - LoadSoundFromFile(ClickSoundStream, SoundPath + 'rimshot022b.mp3'); + result := true; +end; -// LoadSoundFromFile(DrumSoundStream, SoundPath + 'bassdrumhard076b.mp3'); -// LoadSoundFromFile(HihatSoundStream, SoundPath + 'hihatclosed068b.mp3'); -// LoadSoundFromFile(ClapSoundStream, SoundPath + 'claps050b.mp3'); +function TAudioPlayback_Bass.Load(Filename: string): TBassPlaybackStream; +var + L: Integer; + stream: HSTREAM; +begin + Result := nil; -// LoadSoundFromFile(ShuffleSoundStream, SoundPath + 'Shuffle.mp3'); + //Log.LogStatus('Loading Sound: "' + Filename + '"', 'LoadSoundFromFile'); + stream := BASS_StreamCreateFile(False, pchar(Filename), 0, 0, 0); + if (stream = 0) then + begin + Log.LogError('Failed to open "' + Filename + '", ' + + TAudioCore_Bass.ErrorGetString(BASS_ErrorGetCode()), 'TAudioPlayback_Bass.Load'); + Exit; + end; -// Log.BenchmarkEnd(4); -// Log.LogBenchmark('--> Loading Sounds', 4); + Result := TBassPlaybackStream.Create(stream); end; procedure TAudioPlayback_Bass.SetVolume(Volume: integer); @@ -240,7 +265,6 @@ begin //Old Sets Wave Volume //BASS_SetVolume(Volume); //New: Sets Volume only for this Application - BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume); BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume); BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume); @@ -248,193 +272,102 @@ end; procedure TAudioPlayback_Bass.SetMusicVolume(Volume: Integer); begin - //Max Volume Prevention - if Volume > 100 then - Volume := 100; - - if Volume < 0 then - Volume := 0; - - //Set Volume - BASS_ChannelSetAttributes (MusicStream, -1, Volume, -101); + if assigned(MusicStream) then + MusicStream.SetVolume(Volume); end; procedure TAudioPlayback_Bass.SetLoop(Enabled: boolean); begin - Loop := Enabled; + if assigned(MusicStream) then + MusicStream.Loop := Enabled; end; -function TAudioPlayback_Bass.Open(Name: string): boolean; +function TAudioPlayback_Bass.Open(Filename: string): boolean; +var + stream: HSTREAM; begin - Loaded := false; - if FileExists(Name) then - begin - MusicStream := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0); + Result := false; - Loaded := true; - //Set Max Volume - SetMusicVolume (100); - end; + // free old MusicStream + if assigned(MusicStream) then + MusicStream.Free; - Result := Loaded; -end; + MusicStream := Load(Filename); + if not assigned(MusicStream) then + Exit; -procedure TAudioPlayback_Bass.Rewind; -begin - if Loaded then begin - end; + //Set Max Volume + SetMusicVolume(100); + + Result := true; end; -procedure TAudioPlayback_Bass.SetPosition(Time: real); -var - bytes: integer; +procedure TAudioPlayback_Bass.Rewind; begin - bytes := BASS_ChannelSeconds2Bytes(MusicStream, Time); - BASS_ChannelSetPosition(MusicStream, bytes); + SetPosition(0); end; procedure TAudioPlayback_Bass.Play; begin - if Loaded then - begin - if Loop then - BASS_ChannelPlay(MusicStream, True); // start from beginning... actually bass itself does not loop, nor does this TAudio_bass Class - - BASS_ChannelPlay(MusicStream, False); // for setting position before playing - end; + if assigned(MusicStream) then + MusicStream.Play(); end; -procedure TAudioPlayback_Bass.Pause; //Pause Mod +procedure TAudioPlayback_Bass.Pause; begin - if Loaded then begin - BASS_ChannelPause(MusicStream); // Pauses Song - end; + if assigned(MusicStream) then + MusicStream.Pause(); end; procedure TAudioPlayback_Bass.Stop; begin - Bass_ChannelStop(MusicStream); + if assigned(MusicStream) then + MusicStream.Stop(); end; procedure TAudioPlayback_Bass.Close; begin - Bass_StreamFree(MusicStream); + if assigned(MusicStream) then + MusicStream.Close(); end; function TAudioPlayback_Bass.Length: real; var bytes: integer; begin - bytes := BASS_ChannelGetLength(MusicStream); - Result := BASS_ChannelBytes2Seconds(MusicStream, bytes); -end; - -function TAudioPlayback_Bass.getPosition: real; -var - bytes: integer; -begin - bytes := BASS_ChannelGetPosition(MusicStream); - Result := BASS_ChannelBytes2Seconds(MusicStream, bytes); -end; - -function TAudioPlayback_Bass.Finished: boolean; -begin - Result := false; - - if BASS_ChannelIsActive(MusicStream) = BASS_ACTIVE_STOPPED then - begin - Result := true; - end; -end; - -procedure TAudioPlayback_Bass.PlayStart; -begin - BASS_ChannelPlay(StartSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayBack; -begin - BASS_ChannelPlay(BackSoundStream, True);// then -end; - -procedure TAudioPlayback_Bass.PlaySwoosh; -begin - BASS_ChannelPlay(SwooshSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayChange; -begin - BASS_ChannelPlay(ChangeSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayOption; -begin - BASS_ChannelPlay(OptionSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayClick; -begin - BASS_ChannelPlay(ClickSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayDrum; -begin - BASS_ChannelPlay(DrumSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayHihat; -begin - BASS_ChannelPlay(HihatSoundStream, True); -end; - -procedure TAudioPlayback_Bass.PlayClap; -begin - BASS_ChannelPlay(ClapSoundStream, True); + if assigned(MusicStream) then + Result := MusicStream.GetLength() + else + Result := -1; end; -procedure TAudioPlayback_Bass.PlayShuffle; +function TAudioPlayback_Bass.GetPosition: real; begin - BASS_ChannelPlay(ShuffleSoundStream, True); + if assigned(MusicStream) then + Result := MusicStream.GetPosition() + else + Result := -1; end; -procedure TAudioPlayback_Bass.StopShuffle; +procedure TAudioPlayback_Bass.SetPosition(Time: real); begin - BASS_ChannelStop(ShuffleSoundStream); + if assigned(MusicStream) then + MusicStream.SetPosition(Time); end; -function TAudioPlayback_Bass.LoadSoundFromFile(var stream: HSTREAM; Name: string): boolean; -var - L: Integer; +function TAudioPlayback_Bass.Finished: boolean; begin - if FileExists(Name) then - begin - Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); - try - stream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0); - - //Add CustomSound - L := High(CustomSounds) + 1; - SetLength (CustomSounds, L + 1); - CustomSounds[L].Filename := Name; - CustomSounds[L].Stream := TBassOutputStream.Create(stream); - except - Log.LogError('Failed to open using BASS', 'LoadSoundFromFile'); - end; - end + if assigned(MusicStream) then + Result := (MusicStream.GetStatus() = ssStopped) else - begin - Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile'); - exit; - end; + Result := true; end; //Equalizer -function TAudioPlayback_Bass.GetFFTData: TFFTData; -var - Data: TFFTData; +procedure TAudioPlayback_Bass.GetFFTData(var data: TFFTData); begin //Get Channel Data Mono and 256 Values - BASS_ChannelGetData(MusicStream, @Result, BASS_DATA_FFT512); + BASS_ChannelGetData(MusicStream.Handle, @data, BASS_DATA_FFT512); end; {* @@ -447,23 +380,21 @@ var nBytes: DWORD; begin //Get Channel Data Mono and 256 Values - BASS_ChannelGetInfo(MusicStream, info); - ZeroMemory(@data, sizeof(TPCMData)); + BASS_ChannelGetInfo(MusicStream.Handle, info); + FillChar(data, sizeof(TPCMData), 0); if (info.chans = 1) then begin // mono file -> add stereo channel - { - nBytes := BASS_ChannelGetData(Bass, @data[0], samples*sizeof(Smallint)); + nBytes := 0;//BASS_ChannelGetData(Bass, @data[0], samples*sizeof(Smallint)); // interleave data //CopyMemory(@data[1], @data[0], samples*sizeof(Smallint)); - } result := 0; end else begin // stereo file - nBytes := BASS_ChannelGetData(MusicStream, @data, sizeof(TPCMData)); + nBytes := BASS_ChannelGetData(MusicStream.Handle, @data, sizeof(TPCMData)); end; if(nBytes <= 0) then result := 0 @@ -471,36 +402,21 @@ begin result := nBytes div sizeof(TPCMStereoSample); end; -function TAudioPlayback_Bass.LoadCustomSound(const Filename: String): Cardinal; -var - S: hStream; - I: Integer; - F: String; +function TAudioPlayback_Bass.OpenSound(const Filename: string): TAudioPlaybackStream; begin - //Search for Sound in already loaded Sounds - F := UpperCase(SoundPath + FileName); - For I := 0 to High(CustomSounds) do - begin - if (UpperCase(CustomSounds[I].Filename) = F) then - begin - Result := I; - Exit; - end; - end; + result := Load(Filename); +end; - if LoadSoundFromFile(S, SoundPath + Filename) then - Result := High(CustomSounds) - else - Result := 0; +procedure TAudioPlayback_Bass.PlaySound(stream: TAudioPlaybackStream); +begin + if assigned(stream) then + stream.Play(); end; -procedure TAudioPlayback_Bass.PlayCustomSound(const Index: Cardinal ); +procedure TAudioPlayback_Bass.StopSound(stream: TAudioPlaybackStream); begin - if Index <= High(CustomSounds) then - with CustomSounds[Index].Stream as TBassOutputStream do - begin - BASS_ChannelPlay(Handle, True); - end; + if assigned(stream) then + stream.Stop(); end; diff --git a/Game/Code/Classes/UAudioPlayback_Portaudio.pas b/Game/Code/Classes/UAudioPlayback_Portaudio.pas index 5f4a8cde..2743fa86 100644 --- a/Game/Code/Classes/UAudioPlayback_Portaudio.pas +++ b/Game/Code/Classes/UAudioPlayback_Portaudio.pas @@ -9,35 +9,40 @@ interface {$I switches.inc} -uses Classes, - SysUtils, - UMusic; +uses + Classes, + SysUtils, + UMusic; implementation uses - {$IFDEF LAZARUS} - lclintf, - {$ifndef win32} - libc, - {$endif} - {$ENDIF} - sdl, - portaudio, - ULog, - UIni, - UMain; + {$IFNDEF Win32} + libc, + {$ENDIF} + sdl, + portaudio, + ULog, + UIni, + UMain; type TPortaudioPlaybackStream = class(TAudioPlaybackStream) private - status: TStreamStatus; - Loaded: boolean; + Status: TStreamStatus; Loop: boolean; + + _volume: integer; + + procedure Reset(); public - decodeStream: TAudioDecodeStream; + DecodeStream: TAudioDecodeStream; + + constructor Create(); + destructor Destroy(); override; + + function SetDecodeStream(decodeStream: TAudioDecodeStream): boolean; - constructor Create(decodeStream: TAudioDecodeStream); procedure Play(); override; procedure Pause(); override; procedure Stop(); override; @@ -49,6 +54,9 @@ type function IsLoaded(): boolean; + function GetVolume(): integer; override; + procedure SetVolume(volume: integer); override; + // functions delegated to the decode stream function GetPosition: real; procedure SetPosition(Time: real); @@ -60,12 +68,23 @@ type private activeStreams: TList; mixerBuffer: PChar; + internalLock: PSDL_Mutex; + + _volume: integer; + + procedure Lock(); inline; + procedure Unlock(); inline; + + function GetVolume(): integer; + procedure SetVolume(volume: integer); public constructor Create(); destructor Destroy(); override; procedure AddStream(stream: TAudioPlaybackStream); procedure RemoveStream(stream: TAudioPlaybackStream); function ReadData(Buffer: PChar; BufSize: integer): integer; + + property Volume: integer READ GetVolume WRITE SetVolume; end; type @@ -73,36 +92,29 @@ type private MusicStream: TPortaudioPlaybackStream; - StartSoundStream: TPortaudioPlaybackStream; - BackSoundStream: TPortaudioPlaybackStream; - SwooshSoundStream: TPortaudioPlaybackStream; - ChangeSoundStream: TPortaudioPlaybackStream; - OptionSoundStream: TPortaudioPlaybackStream; - ClickSoundStream: TPortaudioPlaybackStream; - DrumSoundStream: TPortaudioPlaybackStream; - HihatSoundStream: TPortaudioPlaybackStream; - ClapSoundStream: TPortaudioPlaybackStream; - ShuffleSoundStream: TPortaudioPlaybackStream; - - //Custom Sounds - CustomSounds: array of TCustomSoundEntry; - - mixerStream: TAudioMixerStream; + MixerStream: TAudioMixerStream; paStream: PPaStream; - public - FrameSize: integer; - function GetName: String; + FrameSize: integer; function InitializePortaudio(): boolean; function StartPortaudioStream(): boolean; - procedure InitializePlayback(); + function InitializeSDLAudio(): boolean; + function StartSDLAudioStream(): boolean; + procedure StopSDLAudioStream(); + public + function GetName: String; + + function InitializePlayback(): boolean; + destructor Destroy; override; + + function Load(const Filename: String): TPortaudioPlaybackStream; + procedure SetVolume(Volume: integer); procedure SetMusicVolume(Volume: integer); procedure SetLoop(Enabled: boolean); function Open(Filename: string): boolean; // true if succeed - function Load(Filename: string): TPortaudioPlaybackStream; procedure Rewind; procedure SetPosition(Time: real); procedure Play; @@ -113,27 +125,17 @@ type function Finished: boolean; function Length: real; function GetPosition: real; - procedure PlayStart; - procedure PlayBack; - procedure PlaySwoosh; - procedure PlayChange; - procedure PlayOption; - procedure PlayClick; - procedure PlayDrum; - procedure PlayHihat; - procedure PlayClap; - procedure PlayShuffle; - procedure StopShuffle; - - //Equalizer - function GetFFTData: TFFTData; + + // Equalizer + procedure GetFFTData(var data: TFFTData); // Interface for Visualizer function GetPCMData(var data: TPCMData): Cardinal; - //Custom Sounds - function LoadCustomSound(const Filename: String): Cardinal; - procedure PlayCustomSound(const Index: Cardinal ); + // Sounds + function OpenSound(const Filename: String): TAudioPlaybackStream; + procedure PlaySound(stream: TAudioPlaybackStream); + procedure StopSound(stream: TAudioPlaybackStream); end; @@ -150,25 +152,59 @@ var constructor TAudioMixerStream.Create(); begin activeStreams := TList.Create; + internalLock := SDL_CreateMutex(); + _volume := 100; end; destructor TAudioMixerStream.Destroy(); begin - if (mixerBuffer <> nil) then + if assigned(mixerBuffer) then Freemem(mixerBuffer); activeStreams.Free; + SDL_DestroyMutex(internalLock); +end; + +procedure TAudioMixerStream.Lock(); +begin + SDL_mutexP(internalLock); +end; + +procedure TAudioMixerStream.Unlock(); +begin + SDL_mutexV(internalLock); +end; + +function TAudioMixerStream.GetVolume(): integer; +begin + Lock(); + result := _volume; + Unlock(); +end; + +procedure TAudioMixerStream.SetVolume(volume: integer); +begin + Lock(); + _volume := volume; + Unlock(); end; procedure TAudioMixerStream.AddStream(stream: TAudioPlaybackStream); begin + if not assigned(stream) then + Exit; + + Lock(); // check if stream is already in list to avoid duplicates if (activeStreams.IndexOf(Pointer(stream)) = -1) then activeStreams.Add(Pointer(stream)); + Unlock(); end; procedure TAudioMixerStream.RemoveStream(stream: TAudioPlaybackStream); begin + Lock(); activeStreams.Remove(Pointer(stream)); + Unlock(); end; function TAudioMixerStream.ReadData(Buffer: PChar; BufSize: integer): integer; @@ -176,79 +212,111 @@ var i: integer; size: integer; stream: TPortaudioPlaybackStream; + appVolume: single; begin result := BufSize; // zero target-buffer (silence) FillChar(Buffer^, BufSize, 0); - // resize mixer-buffer + // resize mixer-buffer if necessary ReallocMem(mixerBuffer, BufSize); - if (mixerBuffer = nil) then + if not assigned(mixerBuffer) then Exit; - writeln('Mix: ' + inttostr(activeStreams.Count)); + Lock(); + + //writeln('Mix: ' + inttostr(activeStreams.Count)); + + // use _volume instead of Volume to prevent recursive locking + appVolume := _volume / 100 * SDL_MIX_MAXVOLUME; for i := 0 to activeStreams.Count-1 do begin stream := TPortaudioPlaybackStream(activeStreams[i]); - if (stream.GetStatus() = sPlaying) then + if (stream.GetStatus() = ssPlaying) then begin // fetch data from current stream size := stream.ReadData(mixerBuffer, BufSize); if (size > 0) then begin - SDL_MixAudio(PUInt8(Buffer), PUInt8(mixerBuffer), size, SDL_MIX_MAXVOLUME); + SDL_MixAudio(PUInt8(Buffer), PUInt8(mixerBuffer), size, + Trunc(appVolume * stream.Volume / 100)); end; end; end; + + Unlock(); end; { TPortaudioPlaybackStream } -constructor TPortaudioPlaybackStream.Create(decodeStream: TAudioDecodeStream); +constructor TPortaudioPlaybackStream.Create(); begin inherited Create(); - status := sStopped; - if (decodeStream <> nil) then - begin - Self.decodeStream := decodeStream; - Loaded := true; - end; + Reset(); +end; + +destructor TPortaudioPlaybackStream.Destroy(); +begin + Close(); + inherited Destroy(); +end; + +procedure TPortaudioPlaybackStream.Reset(); +begin + Status := ssStopped; + Loop := false; + DecodeStream := nil; + _volume := 0; +end; + +function TPortaudioPlaybackStream.SetDecodeStream(decodeStream: TAudioDecodeStream): boolean; +begin + result := false; + + Reset(); + + if not assigned(decodeStream) then + Exit; + Self.DecodeStream := decodeStream; + + _volume := 100; + + result := true; +end; + +procedure TPortaudioPlaybackStream.Close(); +begin + Reset(); end; procedure TPortaudioPlaybackStream.Play(); begin - if (status <> sPaused) then + if (status <> ssPaused) then begin // rewind - decodeStream.Position := 0; + if assigned(DecodeStream) then + DecodeStream.Position := 0; end; - status := sPlaying; - //mixerStream.AddStream(Self); + status := ssPlaying; + //MixerStream.AddStream(Self); end; procedure TPortaudioPlaybackStream.Pause(); begin - status := sPaused; + status := ssPaused; end; procedure TPortaudioPlaybackStream.Stop(); begin - status := sStopped; -end; - -procedure TPortaudioPlaybackStream.Close(); -begin - status := sStopped; - Loaded := false; - // TODO: cleanup decode-stream + status := ssStopped; end; function TPortaudioPlaybackStream.IsLoaded(): boolean; begin - result := Loaded; + result := assigned(DecodeStream); end; function TPortaudioPlaybackStream.GetLoop(): boolean; @@ -263,7 +331,10 @@ end; function TPortaudioPlaybackStream.GetLength(): real; begin - result := decodeStream.Length; + if assigned(DecodeStream) then + result := DecodeStream.Length + else + result := -1; end; function TPortaudioPlaybackStream.GetStatus(): TStreamStatus; @@ -273,22 +344,47 @@ end; function TPortaudioPlaybackStream.ReadData(Buffer: PChar; BufSize: integer): integer; begin - result := decodeStream.ReadData(Buffer, BufSize); + if not assigned(DecodeStream) then + begin + result := -1; + Exit; + end; + result := DecodeStream.ReadData(Buffer, BufSize); // end-of-file reached -> stop playback - if (decodeStream.EOF) then + if (DecodeStream.EOF) then begin - status := sStopped; + status := ssStopped; end; end; function TPortaudioPlaybackStream.GetPosition: real; begin - result := decodeStream.Position; + if assigned(DecodeStream) then + result := DecodeStream.Position + else + result := -1; end; procedure TPortaudioPlaybackStream.SetPosition(Time: real); begin - decodeStream.Position := Time; + if assigned(DecodeStream) then + DecodeStream.Position := Time; +end; + +function TPortaudioPlaybackStream.GetVolume(): integer; +begin + result := _volume; +end; + +procedure TPortaudioPlaybackStream.SetVolume(volume: integer); +begin + // clamp volume + if (volume > 100) then + _volume := 100 + else if (volume < 0) then + _volume := 0 + else + _volume := volume; end; @@ -298,18 +394,26 @@ function AudioCallback(input: Pointer; output: Pointer; frameCount: Longword; timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags; userData: Pointer): Integer; cdecl; var - playback : TAudioPlayback_Portaudio; - playbackStream : TPortaudioPlaybackStream; - decodeStream : TAudioDecodeStream; + playback: TAudioPlayback_Portaudio; begin playback := TAudioPlayback_Portaudio(userData); with playback do begin - mixerStream.ReadData(output, frameCount * FrameSize); + MixerStream.ReadData(output, frameCount * FrameSize); end; result := paContinue; end; +procedure SDLAudioCallback(userdata: Pointer; stream: PChar; len: integer); cdecl; +var + playback: TAudioPlayback_Portaudio; +begin + playback := TAudioPlayback_Portaudio(userdata); + with playback do + begin + //MixerStream.ReadData(stream, len); + end; +end; function TAudioPlayback_Portaudio.GetName: String; begin @@ -349,10 +453,11 @@ begin device := paOutDevice; channelCount := 2; sampleFormat := paInt16; - suggestedLatency := paOutDeviceInfo^.defaultLowOutputLatency; + suggestedLatency := paOutDeviceInfo^.defaultHighOutputLatency; hostApiSpecificStreamInfo := nil; end; + // set the size of one audio frame (2channel 16bit uint sample) FrameSize := 2 * sizeof(Smallint); err := Pa_OpenStream(paStream, nil, @paOutParams, 44100, @@ -384,219 +489,208 @@ begin result := true; end; -procedure TAudioPlayback_Portaudio.InitializePlayback; +function TAudioPlayback_Portaudio.InitializeSDLAudio(): boolean; +var + desiredAudioSpec, obtainedAudioSpec: TSDL_AudioSpec; + err: integer; begin - Log.LogStatus('InitializePlayback', 'UAudioPlayback_Portaudio'); + result := false; - InitializePortaudio(); - mixerStream := TAudioMixerStream.Create; + SDL_InitSubSystem(SDL_INIT_AUDIO); - StartSoundStream := Load(SoundPath + 'Common start.mp3'); - BackSoundStream := Load(SoundPath + 'Common back.mp3'); - SwooshSoundStream := Load(SoundPath + 'menu swoosh.mp3'); - ChangeSoundStream := Load(SoundPath + 'select music change music 50.mp3'); - OptionSoundStream := Load(SoundPath + 'option change col.mp3'); - ClickSoundStream := Load(SoundPath + 'rimshot022b.mp3'); + FillChar(desiredAudioSpec, sizeof(desiredAudioSpec), 0); + with desiredAudioSpec do + begin + freq := 44100; + format := AUDIO_S16SYS; + channels := 2; + samples := 1024; // latency: 23 ms + callback := @SDLAudioCallback; + userdata := Self; + end; -// DrumSoundStream := Load(SoundPath + 'bassdrumhard076b.mp3'); -// HihatSoundStream := Load(SoundPath + 'hihatclosed068b.mp3'); -// ClapSoundStream := Load(SoundPath + 'claps050b.mp3'); + // set the size of one audio frame (2channel 16bit uint sample) + FrameSize := 2 * sizeof(Smallint); + + if(SDL_OpenAudio(@desiredAudioSpec, @obtainedAudioSpec) = -1) then + begin + Log.LogStatus('SDL_OpenAudio: ' + SDL_GetError(), 'UAudioPlayback_SDL'); + exit; + end; -// ShuffleSoundStream := Load(SoundPath + 'Shuffle.mp3'); + Log.LogStatus('Opened audio device', 'UAudioPlayback_SDL'); - StartPortaudioStream(); + result := true; end; +function TAudioPlayback_Portaudio.StartSDLAudioStream(): boolean; +begin + SDL_PauseAudio(0); + result := true; +end; -procedure TAudioPlayback_Portaudio.SetVolume(Volume: integer); +procedure TAudioPlayback_Portaudio.StopSDLAudioStream(); begin - //New: Sets Volume only for this Application -(* - BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume); - BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume); - BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume); -*) + SDL_CloseAudio(); end; -procedure TAudioPlayback_Portaudio.SetMusicVolume(Volume: Integer); +function TAudioPlayback_Portaudio.InitializePlayback: boolean; begin - //Max Volume Prevention - if Volume > 100 then - Volume := 100; + result := false; - if Volume < 0 then - Volume := 0; + //Log.LogStatus('InitializePlayback', 'UAudioPlayback_Portaudio'); - //Set Volume -// BASS_ChannelSetAttributes (Bass, -1, Volume, -101); + //if(not InitializePortaudio()) then + if(not InitializeSDLAudio()) then + Exit; + + MixerStream := TAudioMixerStream.Create; + + //if(not StartPortaudioStream()) then; + if(not StartSDLAudioStream()) then + Exit; + + result := true; end; -procedure TAudioPlayback_Portaudio.SetLoop(Enabled: boolean); +destructor TAudioPlayback_Portaudio.Destroy; begin - if (MusicStream <> nil) then - if (MusicStream.IsLoaded) then - MusicStream.SetLoop(Enabled); + StopSDLAudioStream(); + + MixerStream.Free(); + MusicStream.Free(); + + inherited Destroy(); end; -function TAudioPlayback_Portaudio.Open(Filename: string): boolean; +function TAudioPlayback_Portaudio.Load(const Filename: String): TPortaudioPlaybackStream; var decodeStream: TAudioDecodeStream; + playbackStream: TPortaudioPlaybackStream; begin - decodeStream := AudioDecoder.Open(Filename); - MusicStream := TPortaudioPlaybackStream.Create(decodeStream); - // FIXME: remove this line - mixerStream.AddStream(MusicStream); + Result := nil; - if(MusicStream.IsLoaded()) then + decodeStream := AudioDecoder.Open(Filename); + if not assigned(decodeStream) then begin - //Set Max Volume - SetMusicVolume(100); + Log.LogStatus('LoadSoundFromFile: Sound not found "' + Filename + '"', 'UAudioPlayback_Portaudio'); + Exit; end; - Result := MusicStream.IsLoaded(); -end; - -procedure TAudioPlayback_Portaudio.Rewind; -begin - SetPosition(0); -end; + playbackStream := TPortaudioPlaybackStream.Create(); + if (not playbackStream.SetDecodeStream(decodeStream)) then + Exit; -procedure TAudioPlayback_Portaudio.SetPosition(Time: real); -begin - if (MusicStream.IsLoaded) then - begin - MusicStream.SetPosition(Time); - end; -end; + // FIXME: remove this line + MixerStream.AddStream(playbackStream); -function TAudioPlayback_Portaudio.GetPosition: real; -begin - if (MusicStream.IsLoaded) then - Result := MusicStream.GetPosition(); + result := playbackStream; end; -function TAudioPlayback_Portaudio.Length: real; +procedure TAudioPlayback_Portaudio.SetVolume(Volume: integer); begin - Result := 0; - if assigned( MusicStream ) then - if (MusicStream.IsLoaded) then - begin - Result := MusicStream.GetLength(); - end; + // sets volume only for this application + MixerStream.Volume := Volume; end; -procedure TAudioPlayback_Portaudio.Play; +procedure TAudioPlayback_Portaudio.SetMusicVolume(Volume: Integer); begin - if (MusicStream <> nil) then - if (MusicStream.IsLoaded) then - begin - if (MusicStream.GetLoop()) then - begin - end; - // start from beginning... - // actually bass itself does not loop, nor does this TAudio_FFMpeg Class - MusicStream.Play(); - end; + if assigned(MusicStream) then + MusicStream.Volume := Volume; end; -procedure TAudioPlayback_Portaudio.Pause; +procedure TAudioPlayback_Portaudio.SetLoop(Enabled: boolean); begin - if (MusicStream <> nil) then - MusicStream.Pause(); + if assigned(MusicStream) then + MusicStream.SetLoop(Enabled); end; -procedure TAudioPlayback_Portaudio.Stop; +function TAudioPlayback_Portaudio.Open(Filename: string): boolean; +var + decodeStream: TAudioDecodeStream; begin - if MusicStream <> nil then - MusicStream.Stop(); -end; + Result := false; -procedure TAudioPlayback_Portaudio.Close; -begin - if MusicStream <> nil then - MusicStream.Close(); -end; + // free old MusicStream + MusicStream.Free(); -function TAudioPlayback_Portaudio.Finished: boolean; -begin - if MusicStream <> nil then - Result := (MusicStream.GetStatus() = sStopped); -end; + MusicStream := Load(Filename); + if not assigned(MusicStream) then + Exit; -procedure TAudioPlayback_Portaudio.PlayStart; -begin - if StartSoundStream <> nil then - StartSoundStream.Play(); -end; + //Set Max Volume + SetMusicVolume(100); -procedure TAudioPlayback_Portaudio.PlayBack; -begin - if BackSoundStream <> nil then - BackSoundStream.Play(); + Result := true; end; -procedure TAudioPlayback_Portaudio.PlaySwoosh; +procedure TAudioPlayback_Portaudio.Rewind; begin - if SwooshSoundStream <> nil then - SwooshSoundStream.Play(); + SetPosition(0); end; -procedure TAudioPlayback_Portaudio.PlayChange; +procedure TAudioPlayback_Portaudio.SetPosition(Time: real); begin - if ChangeSoundStream <> nil then - ChangeSoundStream.Play(); + if assigned(MusicStream) then + MusicStream.SetPosition(Time); end; -procedure TAudioPlayback_Portaudio.PlayOption; +function TAudioPlayback_Portaudio.GetPosition: real; begin - if OptionSoundStream <> nil then - OptionSoundStream.Play(); + if assigned(MusicStream) then + Result := MusicStream.GetPosition() + else + Result := -1; end; -procedure TAudioPlayback_Portaudio.PlayClick; +function TAudioPlayback_Portaudio.Length: real; begin - if ClickSoundStream <> nil then - ClickSoundStream.Play(); + if assigned(MusicStream) then + Result := MusicStream.GetLength() + else + Result := -1; end; -procedure TAudioPlayback_Portaudio.PlayDrum; +procedure TAudioPlayback_Portaudio.Play; begin - if DrumSoundStream <> nil then - DrumSoundStream.Play(); + if assigned(MusicStream) then + MusicStream.Play(); end; -procedure TAudioPlayback_Portaudio.PlayHihat; +procedure TAudioPlayback_Portaudio.Pause; begin - if HihatSoundStream <> nil then - HihatSoundStream.Play(); + if assigned(MusicStream) then + MusicStream.Pause(); end; -procedure TAudioPlayback_Portaudio.PlayClap; +procedure TAudioPlayback_Portaudio.Stop; begin - if ClapSoundStream <> nil then - ClapSoundStream.Play(); + if assigned(MusicStream) then + MusicStream.Stop(); end; -procedure TAudioPlayback_Portaudio.PlayShuffle; +procedure TAudioPlayback_Portaudio.Close; begin - if ShuffleSoundStream <> nil then - ShuffleSoundStream.Play(); + if assigned(MusicStream) then + begin + MixerStream.RemoveStream(MusicStream); + MusicStream.Close(); + end; end; -procedure TAudioPlayback_Portaudio.StopShuffle; +function TAudioPlayback_Portaudio.Finished: boolean; begin - if ShuffleSoundStream <> nil then - ShuffleSoundStream.Stop(); + if assigned(MusicStream) then + Result := (MusicStream.GetStatus() = ssStopped) + else + Result := true; end; //Equalizer -function TAudioPlayback_Portaudio.GetFFTData: TFFTData; -var - data: TFFTData; +procedure TAudioPlayback_Portaudio.GetFFTData(var data: TFFTData); begin //Get Channel Data Mono and 256 Values // BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512); - result := data; end; // Interface for Visualizer @@ -605,66 +699,24 @@ begin result := 0; end; -function TAudioPlayback_Portaudio.Load(Filename: string): TPortaudioPlaybackStream; -var - decodeStream : TAudioDecodeStream; - playbackStream : TPortaudioPlaybackStream; - csIndex : integer; +function TAudioPlayback_Portaudio.OpenSound(const Filename: String): TAudioPlaybackStream; begin - result := nil; - - decodeStream := AudioDecoder.Open(Filename); - if (decodeStream = nil) then - begin - Log.LogStatus('LoadSoundFromFile: Sound not found "' + Filename + '"', 'UAudioPlayback_Portaudio'); - exit; - end; - - playbackStream := TPortaudioPlaybackStream.Create(decodeStream); - // FIXME: remove this line - mixerStream.AddStream(playbackStream); - - //Add CustomSound - csIndex := High(CustomSounds) + 1; - SetLength(CustomSounds, csIndex + 1); - CustomSounds[csIndex].Filename := Filename; - CustomSounds[csIndex].Stream := playbackStream; - - result := playbackStream; + result := Load(Filename); end; -function TAudioPlayback_Portaudio.LoadCustomSound(const Filename: String): Cardinal; -var - S: TAudioPlaybackStream; - I: Integer; - F: String; +procedure TAudioPlayback_Portaudio.PlaySound(stream: TAudioPlaybackStream); begin - //Search for Sound in already loaded Sounds - F := UpperCase(SoundPath + FileName); - For I := 0 to High(CustomSounds) do - begin - if (UpperCase(CustomSounds[I].Filename) = F) then - begin - Result := I; - Exit; - end; - end; - - S := Load(SoundPath + Filename); - if (S <> nil) then - Result := High(CustomSounds) - else - Result := 0; + if assigned(stream) then + stream.Play(); end; -procedure TAudioPlayback_Portaudio.PlayCustomSound(const Index: Cardinal ); +procedure TAudioPlayback_Portaudio.StopSound(stream: TAudioPlaybackStream); begin - if (Index <= High(CustomSounds)) then - CustomSounds[Index].Stream.Play(); + if assigned(stream) then + stream.Stop(); end; - initialization singleton_AudioPlaybackPortaudio := TAudioPlayback_Portaudio.create(); AudioManager.add( singleton_AudioPlaybackPortaudio ); diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas index 662050dc..a81aa93b 100644 --- a/Game/Code/Classes/UDraw.pas +++ b/Game/Code/Classes/UDraw.pas @@ -161,21 +161,25 @@ end; procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer); var - Pet : integer; + SampleIndex: integer; + Sound: TSound; + MaxX, MaxY: real; begin; -// Log.LogStatus('Oscilloscope', 'SingDraw'); + Sound := AudioInputProcessor.Sound[NrSound]; + + // Log.LogStatus('Oscilloscope', 'SingDraw'); glColor3f(Skin_OscR, Skin_OscG, Skin_OscB); {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then glColor3f(1, 1, 1); } - glBegin(GL_LINE_STRIP); - - glVertex2f(X, -AudioInputProcessor.Sound[NrSound].BufferArray[1] / $10000 * H + Y + H/2); + MaxX := W-1; + MaxY := (H-1) / 2; - for Pet := 2 to AudioInputProcessor.Sound[NrSound].n div 1 do + glBegin(GL_LINE_STRIP); + for SampleIndex := 0 to High(Sound.BufferArray) do begin - glVertex2f( X + (Pet-1) * W / (AudioInputProcessor.Sound[NrSound].n - 1), - -AudioInputProcessor.Sound[NrSound].BufferArray[Pet] / $10000 * H + Y + H/2 ); + glVertex2f(X + MaxX * SampleIndex/High(Sound.BufferArray), + Y + MaxY * (1 - Sound.BufferArray[SampleIndex]/-Low(Smallint))); end; glEnd; end; diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas index 599bb8fa..4ac67cda 100644 --- a/Game/Code/Classes/UIni.pas +++ b/Game/Code/Classes/UIni.pas @@ -1,798 +1,801 @@ -unit UIni; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -uses IniFiles, ULog, SysUtils; - -type - TIni = class - Name: array[0..11] of string; - - // Templates for Names Mod - NameTeam: array[0..2] of string; - NameTemplate: array[0..11] of string; - - //Filename of the opened iniFile - Filename: string; - - // Game - Players: integer; - Difficulty: integer; - Language: integer; - Tabs: integer; - Tabs_at_startup:integer; //Tabs at Startup fix - Sorting: integer; - Debug: integer; - - // Graphics - Screens: integer; - Resolution: integer; - Depth: integer; - FullScreen: integer; - TextureSize: integer; - SingWindow: integer; - Oscilloscope: integer; - Spectrum: integer; - Spectrograph: integer; - MovieSize: integer; - - // Sound - MicBoost: integer; - ClickAssist: integer; - BeatClick: integer; - SavePlayback: integer; - Threshold: integer; - - //Song Preview - PreviewVolume: integer; - PreviewFading: integer; - - // Lyrics - LyricsFont: integer; - LyricsEffect: integer; - Solmization: integer; - - // Themes - Theme: integer; - SkinNo: integer; - Color: integer; - - // Record - Card: integer; // not saved in config.ini - - CardList: array of record - Name: string; - Input: integer; - ChannelL: integer; - ChannelR: integer; - end; - - // Advanced - LoadAnimation: integer; - EffectSing: integer; - ScreenFade: integer; - AskbeforeDel: integer; - OnSongClick: integer; - LineBonus: integer; - PartyPopup: integer; - - // Controller - Joypad: integer; - - // Soundcards - SoundCard: array[0..7, 1..2] of integer; - - // Devices - LPT: integer; - - procedure Load; - procedure Save; - procedure SaveNames; - procedure SaveLevel; - end; - - -var - Ini: TIni; - IResolution: array of string; - ILanguage: array of string; - ITheme: array of string; - ISkin: array of string; - ICard: array of string; - IInput: array of string; - -const - IPlayers: array[0..4] of string = ('1', '2', '3', '4', '6'); - IDifficulty: array[0..2] of string = ('Easy', 'Medium', 'Hard'); - ITabs: array[0..1] of string = ('Off', 'On'); - - ISorting: array[0..7] of string = ('Edition', 'Genre', 'Language', 'Folder', 'Title', 'Artist', 'Title2', 'Artist2'); - sEdition = 0; - sGenre = 1; - sLanguage = 2; - sFolder = 3; - sTitle = 4; - sArtist = 5; - sTitle2 = 6; - sArtist2 = 7; - - IDebug: array[0..1] of string = ('Off', 'On'); - - IScreens: array[0..1] of string = ('1', '2'); - IFullScreen: array[0..1] of string = ('Off', 'On'); - IDepth: array[0..1] of string = ('16 bit', '32 bit'); - ITextureSize: array[0..2] of string = ('128', '256', '512'); - ISingWindow: array[0..1] of string = ('Small', 'Big'); - - //SingBar Mod - IOscilloscope: array[0..2] of string = ('Off', 'Osci', 'Bar'); - //IOscilloscope: array[0..1] of string = ('Off', 'On'); - - ISpectrum: array[0..1] of string = ('Off', 'On'); - ISpectrograph: array[0..1] of string = ('Off', 'On'); - IMovieSize: array[0..2] of string = ('Half', 'Full [Vid]', 'Full [BG+Vid]'); - - IMicBoost: array[0..3] of string = ('Off', '+6dB', '+12dB', '+18dB'); - IClickAssist: array[0..1] of string = ('Off', 'On'); - IBeatClick: array[0..1] of string = ('Off', 'On'); - ISavePlayback: array[0..1] of string = ('Off', 'On'); - IThreshold: array[0..3] of string = ('5%', '10%', '15%', '20%'); - //Song Preview - IPreviewVolume: array[0..10] of string = ('Off', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'); - IPreviewFading: array[0..5] of string = ('Off', '1 Sec', '2 Secs', '3 Secs', '4 Secs', '5 Secs'); - - - ILyricsFont: array[0..2] of string = ('Plain', 'OLine1', 'OLine2'); - ILyricsEffect: array[0..3] of string = ('Simple', 'Zoom', 'Slide', 'Ball'); - ISolmization: array[0..3] of string = ('Off', 'Euro', 'Jap', 'American'); - - IColor: array[0..8] of string = ('Blue', 'Green', 'Pink', 'Red', 'Violet', 'Orange', 'Yellow', 'Brown', 'Black'); - - // Advanced - ILoadAnimation: array[0..1] of string = ('Off', 'On'); - IEffectSing: array[0..1] of string = ('Off', 'On'); - IScreenFade: array [0..1] of String =('Off', 'On'); - IAskbeforeDel: array[0..1] of string = ('Off', 'On'); - IOnSongClick: array[0..2] of string = ('Sing', 'Select Players', 'Open Menu'); - ILineBonus: array[0..2] of string = ('Off', 'At Score', 'At Notes'); - IPartyPopup: array[0..1] of string = ('Off', 'On'); - - IJoypad: array[0..1] of string = ('Off', 'On'); - ILPT: array[0..2] of string = ('Off', 'LCD', 'Lights'); - - IChannel: array[0..6] of string = ('Off', '1', '2', '3', '4', '5', '6'); - -implementation - -uses //UFiles, - UMain, - SDL, - ULanguage, - UPlatform, - USkins, - URecord, - UCommandLine; - -procedure TIni.Load; -var - IniFile: TMemIniFile; - ThemeIni: TMemIniFile; - Tekst: string; - Pet: integer; - B: boolean; - I, I2, I3: integer; - S: string; - Modes: PPSDL_Rect; - SR: TSearchRec; //Skin List Patch - - function GetFileName (S: String):String; - begin - //Result := copy (S,0,StrRScan (PChar(S),char('.'))+1); - Result := copy (S,0,Pos ('.ini',S)-1); - end; - -begin - GamePath := Platform.GetGameUserPath; - - if (Params.ConfigFile <> '') then - try - IniFile := TMemIniFile.Create(Params.ConfigFile); - except - IniFile := TMemIniFile.Create(GamePath + 'config.ini'); - end - else - IniFile := TMemIniFile.Create(GamePath + 'config.ini'); - - - // Name - for I := 0 to 11 do - Ini.Name[I] := IniFile.ReadString('Name', 'P'+IntToStr(I+1), 'Player'+IntToStr(I+1)); - - - // Templates for Names Mod - for I := 0 to 2 do - Ini.NameTeam[I] := IniFile.ReadString('NameTeam', 'T'+IntToStr(I+1), 'Team'+IntToStr(I+1)); - for I := 0 to 11 do - Ini.NameTemplate[I] := IniFile.ReadString('NameTemplate', 'Name'+IntToStr(I+1), 'Template'+IntToStr(I+1)); - - // Players - Tekst := IniFile.ReadString('Game', 'Players', IPlayers[0]); - for Pet := 0 to High(IPlayers) do - if Tekst = IPlayers[Pet] then Ini.Players := Pet; - - // Difficulty - Tekst := IniFile.ReadString('Game', 'Difficulty', 'Easy'); - for Pet := 0 to High(IDifficulty) do - if Tekst = IDifficulty[Pet] then Ini.Difficulty := Pet; - - // Language - Tekst := IniFile.ReadString('Game', 'Language', 'English'); - for Pet := 0 to High(ILanguage) do - if Tekst = ILanguage[Pet] then Ini.Language := Pet; - -// Language.ChangeLanguage(ILanguage[Ini.Language]); - - // Tabs - Tekst := IniFile.ReadString('Game', 'Tabs', ITabs[0]); - for Pet := 0 to High(ITabs) do - if Tekst = ITabs[Pet] then Ini.Tabs := Pet; - - //Tabs at Startup fix - Ini.Tabs_at_startup := Ini.Tabs; - - // Sorting - Tekst := IniFile.ReadString('Game', 'Sorting', ISorting[0]); - for Pet := 0 to High(ISorting) do - if Tekst = ISorting[Pet] then Ini.Sorting := Pet; - - // Debug - Tekst := IniFile.ReadString('Game', 'Debug', IDebug[0]); - for Pet := 0 to High(IDebug) do - if Tekst = IDebug[Pet] then Ini.Debug := Pet; - - //if Ini.Debug = 1 then SongPath := 'E:\UltraStar 03\Songs\'; - - // Screens - Tekst := IniFile.ReadString('Graphics', 'Screens', IScreens[0]); - for Pet := 0 to High(IScreens) do - if Tekst = IScreens[Pet] then Ini.Screens := Pet; - - // FullScreen - Tekst := IniFile.ReadString('Graphics', 'FullScreen', 'On'); - for Pet := 0 to High(IFullScreen) do - if Tekst = IFullScreen[Pet] then Ini.FullScreen := Pet; - - - // Resolution - SetLength(IResolution, 0); - - Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_FULLSCREEN); // Check if there are any modes available - while assigned( Modes^ ) do //this should solve the biggest wine problem | THANKS Linnex (11.11.07) - begin - SetLength(IResolution, Length(IResolution) + 1); - IResolution[High(IResolution)] := IntToStr(Modes^.w) + 'x' + IntToStr(Modes^.h); - Inc(Modes); - end; - - // if no modes were set, then failback to 800x600 - // as per http://sourceforge.net/forum/message.php?msg_id=4544965 - // THANKS : linnex at users.sourceforge.net - if Length(IResolution) < 1 then - begin - SetLength(IResolution, Length(IResolution) + 1); - IResolution[High(IResolution)] := IntToStr(800) + 'x' + IntToStr(600); - Log.LogStatus('SDL_ListModes Defaulted Res To : ' + IResolution[High(IResolution)] , 'Graphics - Resolutions'); - - // Default to fullscreen OFF, in this case ! - Ini.FullScreen := 0; - end; - - // reverse order - for I := 0 to (Length(IResolution) div 2) - 1 do begin - S := IResolution[I]; - IResolution[I] := IResolution[High(IResolution)-I]; - IResolution[High(IResolution)-I] := S; - end; - - Tekst := IniFile.ReadString('Graphics', 'Resolution', '800x600'); - for Pet := 0 to High(IResolution) do - if Tekst = IResolution[Pet] then Ini.Resolution := Pet; - - - // Resolution - Tekst := IniFile.ReadString('Graphics', 'Depth', '32 bit'); - for Pet := 0 to High(IDepth) do - if Tekst = IDepth[Pet] then Ini.Depth := Pet; - - // Texture Size - Tekst := IniFile.ReadString('Graphics', 'TextureSize', ITextureSize[1]); - for Pet := 0 to High(ITextureSize) do - if Tekst = ITextureSize[Pet] then Ini.TextureSize := Pet; - - // SingWindow - Tekst := IniFile.ReadString('Graphics', 'SingWindow', 'Big'); - for Pet := 0 to High(ISingWindow) do - if Tekst = ISingWindow[Pet] then Ini.SingWindow := Pet; - - // Oscilloscope - Tekst := IniFile.ReadString('Graphics', 'Oscilloscope', 'Bar'); - for Pet := 0 to High(IOscilloscope) do - if Tekst = IOscilloscope[Pet] then Ini.Oscilloscope := Pet; - - // Spectrum - Tekst := IniFile.ReadString('Graphics', 'Spectrum', 'Off'); - for Pet := 0 to High(ISpectrum) do - if Tekst = ISpectrum[Pet] then Ini.Spectrum := Pet; - - // Spectrograph - Tekst := IniFile.ReadString('Graphics', 'Spectrograph', 'Off'); - for Pet := 0 to High(ISpectrograph) do - if Tekst = ISpectrograph[Pet] then Ini.Spectrograph := Pet; - - // MovieSize - Tekst := IniFile.ReadString('Graphics', 'MovieSize', IMovieSize[2]); - for Pet := 0 to High(IMovieSize) do - if Tekst = IMovieSize[Pet] then Ini.MovieSize := Pet; - - // MicBoost - Tekst := IniFile.ReadString('Sound', 'MicBoost', 'Off'); - for Pet := 0 to High(IMicBoost) do - if Tekst = IMicBoost[Pet] then Ini.MicBoost := Pet; - - // ClickAssist - Tekst := IniFile.ReadString('Sound', 'ClickAssist', 'Off'); - for Pet := 0 to High(IClickAssist) do - if Tekst = IClickAssist[Pet] then Ini.ClickAssist := Pet; - - // BeatClick - Tekst := IniFile.ReadString('Sound', 'BeatClick', IBeatClick[0]); - for Pet := 0 to High(IBeatClick) do - if Tekst = IBeatClick[Pet] then Ini.BeatClick := Pet; - - // SavePlayback - Tekst := IniFile.ReadString('Sound', 'SavePlayback', ISavePlayback[0]); - for Pet := 0 to High(ISavePlayback) do - if Tekst = ISavePlayback[Pet] then Ini.SavePlayback := Pet; - - // Threshold - Tekst := IniFile.ReadString('Sound', 'Threshold', IThreshold[2]); - for Pet := 0 to High(IThreshold) do - if Tekst = IThreshold[Pet] then Ini.Threshold := Pet; - - //Song Preview - Tekst := IniFile.ReadString('Sound', 'PreviewVolume', IPreviewVolume[7]); - for Pet := 0 to High(IPreviewVolume) do - if Tekst = IPreviewVolume[Pet] then Ini.PreviewVolume := Pet; - - Tekst := IniFile.ReadString('Sound', 'PreviewFading', IPreviewFading[1]); - for Pet := 0 to High(IPreviewFading) do - if Tekst = IPreviewFading[Pet] then Ini.PreviewFading := Pet; - - // Lyrics Font - Tekst := IniFile.ReadString('Lyrics', 'LyricsFont', ILyricsFont[1]); - for Pet := 0 to High(ILyricsFont) do - if Tekst = ILyricsFont[Pet] then Ini.LyricsFont := Pet; - - // Lyrics Effect - Tekst := IniFile.ReadString('Lyrics', 'LyricsEffect', ILyricsEffect[1]); - for Pet := 0 to High(ILyricsEffect) do - if Tekst = ILyricsEffect[Pet] then Ini.LyricsEffect := Pet; - - // Solmization - Tekst := IniFile.ReadString('Lyrics', 'Solmization', ISolmization[0]); - for Pet := 0 to High(ISolmization) do - if Tekst = ISolmization[Pet] then Ini.Solmization := Pet; - - // Theme - - //Theme List Patch - - //I2 Saves the no of the Deluxe (Standard-) Theme - I2 := 0; - //I counts is the cur. Theme no - I := 0; - - SetLength(ITheme, 0); - writeln( 'Searching for Theme : '+ ThemePath + '*.ini' ); - FindFirst(ThemePath + '*.ini',faAnyFile,SR); - Repeat - writeln( SR.Name ); - - //Read Themename from Theme - ThemeIni := TMemIniFile.Create(SR.Name); - Tekst := UpperCase(ThemeIni.ReadString('Theme','Name',GetFileName(SR.Name))); - ThemeIni.Free; - - //if Deluxe Theme then save Themeno to I2 - if (Tekst = 'DELUXE') then - I2 := I; - - //Search for Skins for this Theme - for Pet := low(Skin.Skin) to high(Skin.Skin) do - begin - if UpperCase(Skin.Skin[Pet].Theme) = Tekst then - begin - SetLength(ITheme, Length(ITheme)+1); - ITheme[High(ITheme)] := GetFileName(SR.Name); - break; - end; - end; - - Inc(I); - Until FindNext(SR) <> 0; - FindClose(SR); - //Theme List Patch End } - - //No Theme Found - if (Length(ITheme)=0) then - begin - Log.CriticalError('Could not find any valid Themes.'); - end; - - - Tekst := IniFile.ReadString('Themes', 'Theme', ITheme[I2]); - Ini.Theme := 0; - for Pet := 0 to High(ITheme) do - if Uppercase(Tekst) = Uppercase(ITheme[Pet]) then Ini.Theme := Pet; - - // Skin - Skin.onThemeChange; - Ini.SkinNo := 0; - - Tekst := IniFile.ReadString('Themes', 'Skin', ISkin[0]); - for Pet := 0 to High(ISkin) do - if Tekst = ISkin[Pet] then Ini.SkinNo := Pet; - - // Color - Tekst := IniFile.ReadString('Themes', 'Color', IColor[0]); - for Pet := 0 to High(IColor) do - if Tekst = IColor[Pet] then Ini.Color := Pet; - - // Record - load ini list - SetLength(CardList, 0); - I := 1; - while (IniFile.ValueExists('Record', 'DeviceName' + IntToStr(I)) = true) do begin - //Automatically Delete not Existing Sound Cards - S := IniFile.ReadString('Record', 'DeviceName' + IntToStr(I), ''); - //{ - B := False; - //Look for Soundcard - for I2 := 0 to High(AudioInputProcessor.SoundCard) do - begin - if (S = Trim(AudioInputProcessor.SoundCard[I2].Description)) then - begin - B := True; - Break; - end; - end; - - if B then - begin //} - I3 := Length(CardList); - SetLength(CardList, I3+1); - Ini.CardList[I3].Name := S; - Ini.CardList[I3].Input := IniFile.ReadInteger('Record', 'Input' + IntToStr(I), 0); - Ini.CardList[I3].ChannelL := IniFile.ReadInteger('Record', 'ChannelL' + IntToStr(I), 0); - Ini.CardList[I3].ChannelR := IniFile.ReadInteger('Record', 'ChannelR' + IntToStr(I), 0); - end; - Inc(I); - end; - - // Record - append detected soundcards - for I := 0 to High(AudioInputProcessor.SoundCard) do - begin - B := False; - For I2 := 0 to High(CardList) do - begin //Search for Card in List - if (CardList[I2].Name = Trim(AudioInputProcessor.SoundCard[I].Description)) then - begin - B := True; - Break; - end; - end; - - //If not in List -> Add - If not B then - begin - I3 := Length(CardList); - SetLength(CardList, I3+1); - CardList[I3].Name := Trim(AudioInputProcessor.SoundCard[I].Description); - CardList[I3].Input := 0; - CardList[I3].ChannelL := 0; - CardList[I3].ChannelR := 0; - // default for new users - if (Length(CardList) = 1) then - CardList[I].ChannelL := 1; - end; - end; - - //Advanced Settings - - // LoadAnimation - Tekst := IniFile.ReadString('Advanced', 'LoadAnimation', 'On'); - for Pet := 0 to High(ILoadAnimation) do - if Tekst = ILoadAnimation[Pet] then Ini.LoadAnimation := Pet; - - // ScreenFade - Tekst := IniFile.ReadString('Advanced', 'ScreenFade', 'On'); - for Pet := 0 to High(IScreenFade) do - if Tekst = IScreenFade[Pet] then Ini.ScreenFade := Pet; - - // EffectSing - Tekst := IniFile.ReadString('Advanced', 'EffectSing', 'On'); - for Pet := 0 to High(IEffectSing) do - if Tekst = IEffectSing[Pet] then Ini.EffectSing := Pet; - - // AskbeforeDel - Tekst := IniFile.ReadString('Advanced', 'AskbeforeDel', 'On'); - for Pet := 0 to High(IAskbeforeDel) do - if Tekst = IAskbeforeDel[Pet] then Ini.AskbeforeDel := Pet; - - // OnSongClick - Tekst := IniFile.ReadString('Advanced', 'OnSongClick', 'Sing'); - for Pet := 0 to High(IOnSongClick) do - if Tekst = IOnSongClick[Pet] then Ini.OnSongClick := Pet; - - // Linebonus - Tekst := IniFile.ReadString('Advanced', 'LineBonus', 'At Score'); - for Pet := 0 to High(ILineBonus) do - if Tekst = ILineBonus[Pet] then Ini.LineBonus := Pet; - - // PartyPopup - Tekst := IniFile.ReadString('Advanced', 'PartyPopup', 'On'); - for Pet := 0 to High(IPartyPopup) do - if Tekst = IPartyPopup[Pet] then Ini.PartyPopup := Pet; - - - // Joypad - Tekst := IniFile.ReadString('Controller', 'Joypad', IJoypad[0]); - for Pet := 0 to High(IJoypad) do - if Tekst = IJoypad[Pet] then Ini.Joypad := Pet; - - // LCD - Tekst := IniFile.ReadString('Devices', 'LPT', ILPT[0]); - for Pet := 0 to High(ILPT) do - if Tekst = ILPT[Pet] then Ini.LPT := Pet; - - - // SongPath - if (Params.SongPath <> '') then - SongPath := IncludeTrailingPathDelimiter(Params.SongPath) - else - SongPath := IncludeTrailingPathDelimiter(IniFile.ReadString('Path', 'Songs', SongPath)); - - Filename := IniFile.FileName; - IniFile.Free; -end; - -procedure TIni.Save; -var - IniFile: TIniFile; - Tekst: string; - I: Integer; - S: String; -begin - //if not (FileExists(GamePath + 'config.ini') and FileIsReadOnly(GamePath + 'config.ini')) then begin - if not (FileExists(Filename) and FileIsReadOnly(Filename)) then begin - - IniFile := TIniFile.Create(Filename); - - // Players - Tekst := IPlayers[Ini.Players]; - IniFile.WriteString('Game', 'Players', Tekst); - - // Difficulty - Tekst := IDifficulty[Ini.Difficulty]; - IniFile.WriteString('Game', 'Difficulty', Tekst); - - // Language - Tekst := ILanguage[Ini.Language]; - IniFile.WriteString('Game', 'Language', Tekst); - - // Tabs - Tekst := ITabs[Ini.Tabs]; - IniFile.WriteString('Game', 'Tabs', Tekst); - - // Sorting - Tekst := ISorting[Ini.Sorting]; - IniFile.WriteString('Game', 'Sorting', Tekst); - - // Debug - Tekst := IDebug[Ini.Debug]; - IniFile.WriteString('Game', 'Debug', Tekst); - - // Screens - Tekst := IScreens[Ini.Screens]; - IniFile.WriteString('Graphics', 'Screens', Tekst); - - // FullScreen - Tekst := IFullScreen[Ini.FullScreen]; - IniFile.WriteString('Graphics', 'FullScreen', Tekst); - - // Resolution - Tekst := IResolution[Ini.Resolution]; - IniFile.WriteString('Graphics', 'Resolution', Tekst); - - // Depth - Tekst := IDepth[Ini.Depth]; - IniFile.WriteString('Graphics', 'Depth', Tekst); - - // Resolution - Tekst := ITextureSize[Ini.TextureSize]; - IniFile.WriteString('Graphics', 'TextureSize', Tekst); - - // Sing Window - Tekst := ISingWindow[Ini.SingWindow]; - IniFile.WriteString('Graphics', 'SingWindow', Tekst); - - // Oscilloscope - Tekst := IOscilloscope[Ini.Oscilloscope]; - IniFile.WriteString('Graphics', 'Oscilloscope', Tekst); - - // Spectrum - Tekst := ISpectrum[Ini.Spectrum]; - IniFile.WriteString('Graphics', 'Spectrum', Tekst); - - // Spectrograph - Tekst := ISpectrograph[Ini.Spectrograph]; - IniFile.WriteString('Graphics', 'Spectrograph', Tekst); - - // Movie Size - Tekst := IMovieSize[Ini.MovieSize]; - IniFile.WriteString('Graphics', 'MovieSize', Tekst); - - // MicBoost - Tekst := IMicBoost[Ini.MicBoost]; - IniFile.WriteString('Sound', 'MicBoost', Tekst); - - // ClickAssist - Tekst := IClickAssist[Ini.ClickAssist]; - IniFile.WriteString('Sound', 'ClickAssist', Tekst); - - // BeatClick - Tekst := IBeatClick[Ini.BeatClick]; - IniFile.WriteString('Sound', 'BeatClick', Tekst); - - // Threshold - Tekst := IThreshold[Ini.Threshold]; - IniFile.WriteString('Sound', 'Threshold', Tekst); - - // Song Preview - Tekst := IPreviewVolume[Ini.PreviewVolume]; - IniFile.WriteString('Sound', 'PreviewVolume', Tekst); - - Tekst := IPreviewFading[Ini.PreviewFading]; - IniFile.WriteString('Sound', 'PreviewFading', Tekst); - - // SavePlayback - Tekst := ISavePlayback[Ini.SavePlayback]; - IniFile.WriteString('Sound', 'SavePlayback', Tekst); - - // Lyrics Font - Tekst := ILyricsFont[Ini.LyricsFont]; - IniFile.WriteString('Lyrics', 'LyricsFont', Tekst); - - // Lyrics Effect - Tekst := ILyricsEffect[Ini.LyricsEffect]; - IniFile.WriteString('Lyrics', 'LyricsEffect', Tekst); - - // Solmization - Tekst := ISolmization[Ini.Solmization]; - IniFile.WriteString('Lyrics', 'Solmization', Tekst); - - // Theme - Tekst := ITheme[Ini.Theme]; - IniFile.WriteString('Themes', 'Theme', Tekst); - - // Skin - Tekst := ISkin[Ini.SkinNo]; - IniFile.WriteString('Themes', 'Skin', Tekst); - - // Color - Tekst := IColor[Ini.Color]; - IniFile.WriteString('Themes', 'Color', Tekst); - - // Record - for I := 0 to High(CardList) do begin - S := IntToStr(I+1); - - Tekst := CardList[I].Name; - IniFile.WriteString('Record', 'DeviceName' + S, Tekst); - - Tekst := IntToStr(CardList[I].Input); - IniFile.WriteString('Record', 'Input' + S, Tekst); - - Tekst := IntToStr(CardList[I].ChannelL); - IniFile.WriteString('Record', 'ChannelL' + S, Tekst); - - Tekst := IntToStr(CardList[I].ChannelR); - IniFile.WriteString('Record', 'ChannelR' + S, Tekst); - end; - - //Log.LogError(InttoStr(Length(CardList)) + ' Cards Saved'); - - //Advanced Settings - - //LoadAnimation - Tekst := ILoadAnimation[Ini.LoadAnimation]; - IniFile.WriteString('Advanced', 'LoadAnimation', Tekst); - - //EffectSing - Tekst := IEffectSing[Ini.EffectSing]; - IniFile.WriteString('Advanced', 'EffectSing', Tekst); - - //ScreenFade - Tekst := IScreenFade[Ini.ScreenFade]; - IniFile.WriteString('Advanced', 'ScreenFade', Tekst); - - //AskbeforeDel - Tekst := IAskbeforeDel[Ini.AskbeforeDel]; - IniFile.WriteString('Advanced', 'AskbeforeDel', Tekst); - - //OnSongClick - Tekst := IOnSongClick[Ini.OnSongClick]; - IniFile.WriteString('Advanced', 'OnSongClick', Tekst); - - //Line Bonus - Tekst := ILineBonus[Ini.LineBonus]; - IniFile.WriteString('Advanced', 'LineBonus', Tekst); - - //Party Popup - Tekst := IPartyPopup[Ini.PartyPopup]; - IniFile.WriteString('Advanced', 'PartyPopup', Tekst); - - // Joypad - Tekst := IJoypad[Ini.Joypad]; - IniFile.WriteString('Controller', 'Joypad', Tekst); - - IniFile.Free; - end; -end; - -procedure TIni.SaveNames; -var - IniFile: TIniFile; - I: integer; -begin - //if not FileIsReadOnly(GamePath + 'config.ini') then begin - //IniFile := TIniFile.Create(GamePath + 'config.ini'); - if not FileIsReadOnly(Filename) then begin - IniFile := TIniFile.Create(Filename); - - //Name - // Templates for Names Mod - for I := 1 to 12 do - IniFile.WriteString('Name', 'P' + IntToStr(I), Ini.Name[I-1]); - for I := 1 to 3 do - IniFile.WriteString('NameTeam', 'T' + IntToStr(I), Ini.NameTeam[I-1]); - for I := 1 to 12 do - IniFile.WriteString('NameTemplate', 'Name' + IntToStr(I), Ini.NameTemplate[I-1]); - - IniFile.Free; - end; -end; - -procedure TIni.SaveLevel; -var - IniFile: TIniFile; - I: integer; -begin - //if not FileIsReadOnly(GamePath + 'config.ini') then begin - //IniFile := TIniFile.Create(GamePath + 'config.ini'); - if not FileIsReadOnly(Filename) then begin - IniFile := TIniFile.Create(Filename); - - // Difficulty - IniFile.WriteString('Game', 'Difficulty', IDifficulty[Ini.Difficulty]); - - IniFile.Free; - end; -end; - -end. +unit UIni;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses IniFiles, ULog, SysUtils;
+
+type
+ PInputDeviceConfig = ^TInputDeviceConfig;
+ TInputDeviceConfig = record
+ Name: string;
+ Input: integer;
+ ChannelToPlayerMap: array[0..1] of integer;
+ end;
+
+type
+ TIni = class
+ Name: array[0..11] of string;
+
+ // Templates for Names Mod
+ NameTeam: array[0..2] of string;
+ NameTemplate: array[0..11] of string;
+
+ //Filename of the opened iniFile
+ Filename: string;
+
+ // Game
+ Players: integer;
+ Difficulty: integer;
+ Language: integer;
+ Tabs: integer;
+ Tabs_at_startup:integer; //Tabs at Startup fix
+ Sorting: integer;
+ Debug: integer;
+
+ // Graphics
+ Screens: integer;
+ Resolution: integer;
+ Depth: integer;
+ FullScreen: integer;
+ TextureSize: integer;
+ SingWindow: integer;
+ Oscilloscope: integer;
+ Spectrum: integer;
+ Spectrograph: integer;
+ MovieSize: integer;
+
+ // Sound
+ MicBoost: integer;
+ ClickAssist: integer;
+ BeatClick: integer;
+ SavePlayback: integer;
+ Threshold: integer;
+
+ //Song Preview
+ PreviewVolume: integer;
+ PreviewFading: integer;
+
+ // Lyrics
+ LyricsFont: integer;
+ LyricsEffect: integer;
+ Solmization: integer;
+
+ // Themes
+ Theme: integer;
+ SkinNo: integer;
+ Color: integer;
+
+ // Record
+ InputDeviceConfig: array of TInputDeviceConfig;
+
+ // Advanced
+ LoadAnimation: integer;
+ EffectSing: integer;
+ ScreenFade: integer;
+ AskbeforeDel: integer;
+ OnSongClick: integer;
+ LineBonus: integer;
+ PartyPopup: integer;
+
+ // Controller
+ Joypad: integer;
+
+ // Soundcards
+ SoundCard: array[0..7, 1..2] of integer;
+
+ // Devices
+ LPT: integer;
+
+ procedure Load;
+ procedure Save;
+ procedure SaveNames;
+ procedure SaveLevel;
+ end;
+
+
+var
+ Ini: TIni;
+ IResolution: array of string;
+ ILanguage: array of string;
+ ITheme: array of string;
+ ISkin: array of string;
+ ICard: array of string;
+ IInput: array of string;
+
+const
+ IPlayers: array[0..4] of string = ('1', '2', '3', '4', '6');
+ IDifficulty: array[0..2] of string = ('Easy', 'Medium', 'Hard');
+ ITabs: array[0..1] of string = ('Off', 'On');
+
+ ISorting: array[0..7] of string = ('Edition', 'Genre', 'Language', 'Folder', 'Title', 'Artist', 'Title2', 'Artist2');
+ sEdition = 0;
+ sGenre = 1;
+ sLanguage = 2;
+ sFolder = 3;
+ sTitle = 4;
+ sArtist = 5;
+ sTitle2 = 6;
+ sArtist2 = 7;
+
+ IDebug: array[0..1] of string = ('Off', 'On');
+
+ IScreens: array[0..1] of string = ('1', '2');
+ IFullScreen: array[0..1] of string = ('Off', 'On');
+ IDepth: array[0..1] of string = ('16 bit', '32 bit');
+ ITextureSize: array[0..2] of string = ('128', '256', '512');
+ ISingWindow: array[0..1] of string = ('Small', 'Big');
+
+ //SingBar Mod
+ IOscilloscope: array[0..2] of string = ('Off', 'Osci', 'Bar');
+ //IOscilloscope: array[0..1] of string = ('Off', 'On');
+
+ ISpectrum: array[0..1] of string = ('Off', 'On');
+ ISpectrograph: array[0..1] of string = ('Off', 'On');
+ IMovieSize: array[0..2] of string = ('Half', 'Full [Vid]', 'Full [BG+Vid]');
+
+ IMicBoost: array[0..3] of string = ('Off', '+6dB', '+12dB', '+18dB');
+ IClickAssist: array[0..1] of string = ('Off', 'On');
+ IBeatClick: array[0..1] of string = ('Off', 'On');
+ ISavePlayback: array[0..1] of string = ('Off', 'On');
+ IThreshold: array[0..3] of string = ('5%', '10%', '15%', '20%');
+ //Song Preview
+ IPreviewVolume: array[0..10] of string = ('Off', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%');
+ IPreviewFading: array[0..5] of string = ('Off', '1 Sec', '2 Secs', '3 Secs', '4 Secs', '5 Secs');
+
+
+ ILyricsFont: array[0..2] of string = ('Plain', 'OLine1', 'OLine2');
+ ILyricsEffect: array[0..3] of string = ('Simple', 'Zoom', 'Slide', 'Ball');
+ ISolmization: array[0..3] of string = ('Off', 'Euro', 'Jap', 'American');
+
+ IColor: array[0..8] of string = ('Blue', 'Green', 'Pink', 'Red', 'Violet', 'Orange', 'Yellow', 'Brown', 'Black');
+
+ // Advanced
+ ILoadAnimation: array[0..1] of string = ('Off', 'On');
+ IEffectSing: array[0..1] of string = ('Off', 'On');
+ IScreenFade: array [0..1] of String =('Off', 'On');
+ IAskbeforeDel: array[0..1] of string = ('Off', 'On');
+ IOnSongClick: array[0..2] of string = ('Sing', 'Select Players', 'Open Menu');
+ ILineBonus: array[0..2] of string = ('Off', 'At Score', 'At Notes');
+ IPartyPopup: array[0..1] of string = ('Off', 'On');
+
+ IJoypad: array[0..1] of string = ('Off', 'On');
+ ILPT: array[0..2] of string = ('Off', 'LCD', 'Lights');
+
+ IChannel: array[0..6] of string = ('Off', '1', '2', '3', '4', '5', '6');
+
+implementation
+
+uses //UFiles,
+ UMain,
+ SDL,
+ ULanguage,
+ UPlatform,
+ USkins,
+ URecord,
+ UCommandLine;
+
+procedure TIni.Load;
+var
+ IniFile: TMemIniFile;
+ ThemeIni: TMemIniFile;
+ Tekst: string;
+ Pet: integer;
+ B: boolean;
+ I, I2, I3: integer;
+ S: string;
+ Modes: PPSDL_Rect;
+ SR: TSearchRec; //Skin List Patch
+
+ function GetFileName (S: String):String;
+ begin
+ //Result := copy (S,0,StrRScan (PChar(S),char('.'))+1);
+ Result := copy (S,0,Pos ('.ini',S)-1);
+ end;
+
+begin
+ GamePath := Platform.GetGameUserPath;
+
+ if (Params.ConfigFile <> '') then
+ try
+ IniFile := TMemIniFile.Create(Params.ConfigFile);
+ except
+ IniFile := TMemIniFile.Create(GamePath + 'config.ini');
+ end
+ else
+ IniFile := TMemIniFile.Create(GamePath + 'config.ini');
+
+
+ // Name
+ for I := 0 to 11 do
+ Ini.Name[I] := IniFile.ReadString('Name', 'P'+IntToStr(I+1), 'Player'+IntToStr(I+1));
+
+
+ // Templates for Names Mod
+ for I := 0 to 2 do
+ Ini.NameTeam[I] := IniFile.ReadString('NameTeam', 'T'+IntToStr(I+1), 'Team'+IntToStr(I+1));
+ for I := 0 to 11 do
+ Ini.NameTemplate[I] := IniFile.ReadString('NameTemplate', 'Name'+IntToStr(I+1), 'Template'+IntToStr(I+1));
+
+ // Players
+ Tekst := IniFile.ReadString('Game', 'Players', IPlayers[0]);
+ for Pet := 0 to High(IPlayers) do
+ if Tekst = IPlayers[Pet] then Ini.Players := Pet;
+
+ // Difficulty
+ Tekst := IniFile.ReadString('Game', 'Difficulty', 'Easy');
+ for Pet := 0 to High(IDifficulty) do
+ if Tekst = IDifficulty[Pet] then Ini.Difficulty := Pet;
+
+ // Language
+ Tekst := IniFile.ReadString('Game', 'Language', 'English');
+ for Pet := 0 to High(ILanguage) do
+ if Tekst = ILanguage[Pet] then Ini.Language := Pet;
+
+// Language.ChangeLanguage(ILanguage[Ini.Language]);
+
+ // Tabs
+ Tekst := IniFile.ReadString('Game', 'Tabs', ITabs[0]);
+ for Pet := 0 to High(ITabs) do
+ if Tekst = ITabs[Pet] then Ini.Tabs := Pet;
+
+ //Tabs at Startup fix
+ Ini.Tabs_at_startup := Ini.Tabs;
+
+ // Sorting
+ Tekst := IniFile.ReadString('Game', 'Sorting', ISorting[0]);
+ for Pet := 0 to High(ISorting) do
+ if Tekst = ISorting[Pet] then Ini.Sorting := Pet;
+
+ // Debug
+ Tekst := IniFile.ReadString('Game', 'Debug', IDebug[0]);
+ for Pet := 0 to High(IDebug) do
+ if Tekst = IDebug[Pet] then Ini.Debug := Pet;
+
+ //if Ini.Debug = 1 then SongPath := 'E:\UltraStar 03\Songs\';
+
+ // Screens
+ Tekst := IniFile.ReadString('Graphics', 'Screens', IScreens[0]);
+ for Pet := 0 to High(IScreens) do
+ if Tekst = IScreens[Pet] then Ini.Screens := Pet;
+
+ // FullScreen
+ Tekst := IniFile.ReadString('Graphics', 'FullScreen', 'On');
+ for Pet := 0 to High(IFullScreen) do
+ if Tekst = IFullScreen[Pet] then Ini.FullScreen := Pet;
+
+
+ // Resolution
+ SetLength(IResolution, 0);
+
+ Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_FULLSCREEN); // Check if there are any modes available
+ while assigned( Modes^ ) do //this should solve the biggest wine problem | THANKS Linnex (11.11.07)
+ begin
+ SetLength(IResolution, Length(IResolution) + 1);
+ IResolution[High(IResolution)] := IntToStr(Modes^.w) + 'x' + IntToStr(Modes^.h);
+ Inc(Modes);
+ end;
+
+ // if no modes were set, then failback to 800x600
+ // as per http://sourceforge.net/forum/message.php?msg_id=4544965
+ // THANKS : linnex at users.sourceforge.net
+ if Length(IResolution) < 1 then
+ begin
+ SetLength(IResolution, Length(IResolution) + 1);
+ IResolution[High(IResolution)] := IntToStr(800) + 'x' + IntToStr(600);
+ Log.LogStatus('SDL_ListModes Defaulted Res To : ' + IResolution[High(IResolution)] , 'Graphics - Resolutions');
+
+ // Default to fullscreen OFF, in this case !
+ Ini.FullScreen := 0;
+ end;
+
+ // reverse order
+ for I := 0 to (Length(IResolution) div 2) - 1 do begin
+ S := IResolution[I];
+ IResolution[I] := IResolution[High(IResolution)-I];
+ IResolution[High(IResolution)-I] := S;
+ end;
+
+ Tekst := IniFile.ReadString('Graphics', 'Resolution', '800x600');
+ for Pet := 0 to High(IResolution) do
+ if Tekst = IResolution[Pet] then Ini.Resolution := Pet;
+
+
+ // Resolution
+ Tekst := IniFile.ReadString('Graphics', 'Depth', '32 bit');
+ for Pet := 0 to High(IDepth) do
+ if Tekst = IDepth[Pet] then Ini.Depth := Pet;
+
+ // Texture Size
+ Tekst := IniFile.ReadString('Graphics', 'TextureSize', ITextureSize[1]);
+ for Pet := 0 to High(ITextureSize) do
+ if Tekst = ITextureSize[Pet] then Ini.TextureSize := Pet;
+
+ // SingWindow
+ Tekst := IniFile.ReadString('Graphics', 'SingWindow', 'Big');
+ for Pet := 0 to High(ISingWindow) do
+ if Tekst = ISingWindow[Pet] then Ini.SingWindow := Pet;
+
+ // Oscilloscope
+ Tekst := IniFile.ReadString('Graphics', 'Oscilloscope', 'Bar');
+ for Pet := 0 to High(IOscilloscope) do
+ if Tekst = IOscilloscope[Pet] then Ini.Oscilloscope := Pet;
+
+ // Spectrum
+ Tekst := IniFile.ReadString('Graphics', 'Spectrum', 'Off');
+ for Pet := 0 to High(ISpectrum) do
+ if Tekst = ISpectrum[Pet] then Ini.Spectrum := Pet;
+
+ // Spectrograph
+ Tekst := IniFile.ReadString('Graphics', 'Spectrograph', 'Off');
+ for Pet := 0 to High(ISpectrograph) do
+ if Tekst = ISpectrograph[Pet] then Ini.Spectrograph := Pet;
+
+ // MovieSize
+ Tekst := IniFile.ReadString('Graphics', 'MovieSize', IMovieSize[2]);
+ for Pet := 0 to High(IMovieSize) do
+ if Tekst = IMovieSize[Pet] then Ini.MovieSize := Pet;
+
+ // MicBoost
+ Tekst := IniFile.ReadString('Sound', 'MicBoost', 'Off');
+ for Pet := 0 to High(IMicBoost) do
+ if Tekst = IMicBoost[Pet] then Ini.MicBoost := Pet;
+
+ // ClickAssist
+ Tekst := IniFile.ReadString('Sound', 'ClickAssist', 'Off');
+ for Pet := 0 to High(IClickAssist) do
+ if Tekst = IClickAssist[Pet] then Ini.ClickAssist := Pet;
+
+ // BeatClick
+ Tekst := IniFile.ReadString('Sound', 'BeatClick', IBeatClick[0]);
+ for Pet := 0 to High(IBeatClick) do
+ if Tekst = IBeatClick[Pet] then Ini.BeatClick := Pet;
+
+ // SavePlayback
+ Tekst := IniFile.ReadString('Sound', 'SavePlayback', ISavePlayback[0]);
+ for Pet := 0 to High(ISavePlayback) do
+ if Tekst = ISavePlayback[Pet] then Ini.SavePlayback := Pet;
+
+ // Threshold
+ Tekst := IniFile.ReadString('Sound', 'Threshold', IThreshold[2]);
+ for Pet := 0 to High(IThreshold) do
+ if Tekst = IThreshold[Pet] then Ini.Threshold := Pet;
+
+ //Song Preview
+ Tekst := IniFile.ReadString('Sound', 'PreviewVolume', IPreviewVolume[7]);
+ for Pet := 0 to High(IPreviewVolume) do
+ if Tekst = IPreviewVolume[Pet] then Ini.PreviewVolume := Pet;
+
+ Tekst := IniFile.ReadString('Sound', 'PreviewFading', IPreviewFading[1]);
+ for Pet := 0 to High(IPreviewFading) do
+ if Tekst = IPreviewFading[Pet] then Ini.PreviewFading := Pet;
+
+ // Lyrics Font
+ Tekst := IniFile.ReadString('Lyrics', 'LyricsFont', ILyricsFont[1]);
+ for Pet := 0 to High(ILyricsFont) do
+ if Tekst = ILyricsFont[Pet] then Ini.LyricsFont := Pet;
+
+ // Lyrics Effect
+ Tekst := IniFile.ReadString('Lyrics', 'LyricsEffect', ILyricsEffect[1]);
+ for Pet := 0 to High(ILyricsEffect) do
+ if Tekst = ILyricsEffect[Pet] then Ini.LyricsEffect := Pet;
+
+ // Solmization
+ Tekst := IniFile.ReadString('Lyrics', 'Solmization', ISolmization[0]);
+ for Pet := 0 to High(ISolmization) do
+ if Tekst = ISolmization[Pet] then Ini.Solmization := Pet;
+
+ // Theme
+
+ //Theme List Patch
+
+ //I2 Saves the no of the Deluxe (Standard-) Theme
+ I2 := 0;
+ //I counts is the cur. Theme no
+ I := 0;
+
+ SetLength(ITheme, 0);
+ writeln( 'Searching for Theme : '+ ThemePath + '*.ini' );
+ FindFirst(ThemePath + '*.ini',faAnyFile,SR);
+ Repeat
+ writeln( SR.Name );
+
+ //Read Themename from Theme
+ ThemeIni := TMemIniFile.Create(SR.Name);
+ Tekst := UpperCase(ThemeIni.ReadString('Theme','Name',GetFileName(SR.Name)));
+ ThemeIni.Free;
+
+ //if Deluxe Theme then save Themeno to I2
+ if (Tekst = 'DELUXE') then
+ I2 := I;
+
+ //Search for Skins for this Theme
+ for Pet := low(Skin.Skin) to high(Skin.Skin) do
+ begin
+ if UpperCase(Skin.Skin[Pet].Theme) = Tekst then
+ begin
+ SetLength(ITheme, Length(ITheme)+1);
+ ITheme[High(ITheme)] := GetFileName(SR.Name);
+ break;
+ end;
+ end;
+
+ Inc(I);
+ Until FindNext(SR) <> 0;
+ FindClose(SR);
+ //Theme List Patch End }
+
+ //No Theme Found
+ if (Length(ITheme)=0) then
+ begin
+ Log.CriticalError('Could not find any valid Themes.');
+ end;
+
+
+ Tekst := IniFile.ReadString('Themes', 'Theme', ITheme[I2]);
+ Ini.Theme := 0;
+ for Pet := 0 to High(ITheme) do
+ if Uppercase(Tekst) = Uppercase(ITheme[Pet]) then Ini.Theme := Pet;
+
+ // Skin
+ Skin.onThemeChange;
+ Ini.SkinNo := 0;
+
+ Tekst := IniFile.ReadString('Themes', 'Skin', ISkin[0]);
+ for Pet := 0 to High(ISkin) do
+ if Tekst = ISkin[Pet] then Ini.SkinNo := Pet;
+
+ // Color
+ Tekst := IniFile.ReadString('Themes', 'Color', IColor[0]);
+ for Pet := 0 to High(IColor) do
+ if Tekst = IColor[Pet] then Ini.Color := Pet;
+
+ // Input devices - load ini list
+ SetLength(InputDeviceConfig, 0);
+ I := 1;
+ while (IniFile.ValueExists('Record', 'DeviceName'+IntToStr(I))) do begin
+ // resize list
+ SetLength(InputDeviceConfig, Length(InputDeviceConfig)+1);
+ I2 := High(InputDeviceConfig);
+
+ // read an input device's config.
+ // Note: All devices are appended to the list whether they exist or not.
+ // Otherwise an external device's config will be lost if it is not
+ // connected (e.g. singstar mics or USB-Audio devices).
+ InputDeviceConfig[I2].Name :=
+ IniFile.ReadString('Record', 'DeviceName'+IntToStr(I), '');
+ InputDeviceConfig[I2].Input :=
+ IniFile.ReadInteger('Record', 'Input'+IntToStr(I), 0);
+ InputDeviceConfig[I2].ChannelToPlayerMap[0] :=
+ IniFile.ReadInteger('Record', 'ChannelL'+IntToStr(I), 0);
+ InputDeviceConfig[I2].ChannelToPlayerMap[1] :=
+ IniFile.ReadInteger('Record', 'ChannelR'+IntToStr(I), 0);
+
+ Inc(I);
+ end;
+
+ // Input devices - append detected soundcards
+ for I := 0 to High(AudioInputProcessor.Device) do
+ begin
+ B := False;
+ For I2 := 0 to High(InputDeviceConfig) do
+ begin //Search for Card in List
+ if (InputDeviceConfig[I2].Name = Trim(AudioInputProcessor.Device[I].Description)) then
+ begin
+ B := True;
+ // associate ini-index with device
+ AudioInputProcessor.Device[I].CfgIndex := I2;
+ Break;
+ end;
+ end;
+
+ //If not in List -> Add
+ If not B then
+ begin
+ // resize list
+ SetLength(InputDeviceConfig, Length(InputDeviceConfig)+1);
+ I2 := High(InputDeviceConfig);
+
+ InputDeviceConfig[I2].Name := Trim(AudioInputProcessor.Device[I].Description);
+ InputDeviceConfig[I2].Input := 0;
+ InputDeviceConfig[I2].ChannelToPlayerMap[0] := 0;
+ InputDeviceConfig[I2].ChannelToPlayerMap[1] := 0;
+
+ // associate ini-index with device
+ AudioInputProcessor.Device[I].CfgIndex := I2;
+
+ // set default at first start of USDX (1st device, 1st channel -> player1)
+ if (I2 = 0) then
+ InputDeviceConfig[I2].ChannelToPlayerMap[0] := 1;
+ end;
+ end;
+
+ //Advanced Settings
+
+ // LoadAnimation
+ Tekst := IniFile.ReadString('Advanced', 'LoadAnimation', 'On');
+ for Pet := 0 to High(ILoadAnimation) do
+ if Tekst = ILoadAnimation[Pet] then Ini.LoadAnimation := Pet;
+
+ // ScreenFade
+ Tekst := IniFile.ReadString('Advanced', 'ScreenFade', 'On');
+ for Pet := 0 to High(IScreenFade) do
+ if Tekst = IScreenFade[Pet] then Ini.ScreenFade := Pet;
+
+ // EffectSing
+ Tekst := IniFile.ReadString('Advanced', 'EffectSing', 'On');
+ for Pet := 0 to High(IEffectSing) do
+ if Tekst = IEffectSing[Pet] then Ini.EffectSing := Pet;
+
+ // AskbeforeDel
+ Tekst := IniFile.ReadString('Advanced', 'AskbeforeDel', 'On');
+ for Pet := 0 to High(IAskbeforeDel) do
+ if Tekst = IAskbeforeDel[Pet] then Ini.AskbeforeDel := Pet;
+
+ // OnSongClick
+ Tekst := IniFile.ReadString('Advanced', 'OnSongClick', 'Sing');
+ for Pet := 0 to High(IOnSongClick) do
+ if Tekst = IOnSongClick[Pet] then Ini.OnSongClick := Pet;
+
+ // Linebonus
+ Tekst := IniFile.ReadString('Advanced', 'LineBonus', 'At Score');
+ for Pet := 0 to High(ILineBonus) do
+ if Tekst = ILineBonus[Pet] then Ini.LineBonus := Pet;
+
+ // PartyPopup
+ Tekst := IniFile.ReadString('Advanced', 'PartyPopup', 'On');
+ for Pet := 0 to High(IPartyPopup) do
+ if Tekst = IPartyPopup[Pet] then Ini.PartyPopup := Pet;
+
+
+ // Joypad
+ Tekst := IniFile.ReadString('Controller', 'Joypad', IJoypad[0]);
+ for Pet := 0 to High(IJoypad) do
+ if Tekst = IJoypad[Pet] then Ini.Joypad := Pet;
+
+ // LCD
+ Tekst := IniFile.ReadString('Devices', 'LPT', ILPT[0]);
+ for Pet := 0 to High(ILPT) do
+ if Tekst = ILPT[Pet] then Ini.LPT := Pet;
+
+
+ // SongPath
+ if (Params.SongPath <> '') then
+ SongPath := IncludeTrailingPathDelimiter(Params.SongPath)
+ else
+ SongPath := IncludeTrailingPathDelimiter(IniFile.ReadString('Path', 'Songs', SongPath));
+
+ Filename := IniFile.FileName;
+ IniFile.Free;
+end;
+
+procedure TIni.Save;
+var
+ IniFile: TIniFile;
+ Tekst: string;
+ I: Integer;
+ S: String;
+begin
+ //if not (FileExists(GamePath + 'config.ini') and FileIsReadOnly(GamePath + 'config.ini')) then begin
+ if not (FileExists(Filename) and FileIsReadOnly(Filename)) then begin
+
+ IniFile := TIniFile.Create(Filename);
+
+ // Players
+ Tekst := IPlayers[Ini.Players];
+ IniFile.WriteString('Game', 'Players', Tekst);
+
+ // Difficulty
+ Tekst := IDifficulty[Ini.Difficulty];
+ IniFile.WriteString('Game', 'Difficulty', Tekst);
+
+ // Language
+ Tekst := ILanguage[Ini.Language];
+ IniFile.WriteString('Game', 'Language', Tekst);
+
+ // Tabs
+ Tekst := ITabs[Ini.Tabs];
+ IniFile.WriteString('Game', 'Tabs', Tekst);
+
+ // Sorting
+ Tekst := ISorting[Ini.Sorting];
+ IniFile.WriteString('Game', 'Sorting', Tekst);
+
+ // Debug
+ Tekst := IDebug[Ini.Debug];
+ IniFile.WriteString('Game', 'Debug', Tekst);
+
+ // Screens
+ Tekst := IScreens[Ini.Screens];
+ IniFile.WriteString('Graphics', 'Screens', Tekst);
+
+ // FullScreen
+ Tekst := IFullScreen[Ini.FullScreen];
+ IniFile.WriteString('Graphics', 'FullScreen', Tekst);
+
+ // Resolution
+ Tekst := IResolution[Ini.Resolution];
+ IniFile.WriteString('Graphics', 'Resolution', Tekst);
+
+ // Depth
+ Tekst := IDepth[Ini.Depth];
+ IniFile.WriteString('Graphics', 'Depth', Tekst);
+
+ // Resolution
+ Tekst := ITextureSize[Ini.TextureSize];
+ IniFile.WriteString('Graphics', 'TextureSize', Tekst);
+
+ // Sing Window
+ Tekst := ISingWindow[Ini.SingWindow];
+ IniFile.WriteString('Graphics', 'SingWindow', Tekst);
+
+ // Oscilloscope
+ Tekst := IOscilloscope[Ini.Oscilloscope];
+ IniFile.WriteString('Graphics', 'Oscilloscope', Tekst);
+
+ // Spectrum
+ Tekst := ISpectrum[Ini.Spectrum];
+ IniFile.WriteString('Graphics', 'Spectrum', Tekst);
+
+ // Spectrograph
+ Tekst := ISpectrograph[Ini.Spectrograph];
+ IniFile.WriteString('Graphics', 'Spectrograph', Tekst);
+
+ // Movie Size
+ Tekst := IMovieSize[Ini.MovieSize];
+ IniFile.WriteString('Graphics', 'MovieSize', Tekst);
+
+ // MicBoost
+ Tekst := IMicBoost[Ini.MicBoost];
+ IniFile.WriteString('Sound', 'MicBoost', Tekst);
+
+ // ClickAssist
+ Tekst := IClickAssist[Ini.ClickAssist];
+ IniFile.WriteString('Sound', 'ClickAssist', Tekst);
+
+ // BeatClick
+ Tekst := IBeatClick[Ini.BeatClick];
+ IniFile.WriteString('Sound', 'BeatClick', Tekst);
+
+ // Threshold
+ Tekst := IThreshold[Ini.Threshold];
+ IniFile.WriteString('Sound', 'Threshold', Tekst);
+
+ // Song Preview
+ Tekst := IPreviewVolume[Ini.PreviewVolume];
+ IniFile.WriteString('Sound', 'PreviewVolume', Tekst);
+
+ Tekst := IPreviewFading[Ini.PreviewFading];
+ IniFile.WriteString('Sound', 'PreviewFading', Tekst);
+
+ // SavePlayback
+ Tekst := ISavePlayback[Ini.SavePlayback];
+ IniFile.WriteString('Sound', 'SavePlayback', Tekst);
+
+ // Lyrics Font
+ Tekst := ILyricsFont[Ini.LyricsFont];
+ IniFile.WriteString('Lyrics', 'LyricsFont', Tekst);
+
+ // Lyrics Effect
+ Tekst := ILyricsEffect[Ini.LyricsEffect];
+ IniFile.WriteString('Lyrics', 'LyricsEffect', Tekst);
+
+ // Solmization
+ Tekst := ISolmization[Ini.Solmization];
+ IniFile.WriteString('Lyrics', 'Solmization', Tekst);
+
+ // Theme
+ Tekst := ITheme[Ini.Theme];
+ IniFile.WriteString('Themes', 'Theme', Tekst);
+
+ // Skin
+ Tekst := ISkin[Ini.SkinNo];
+ IniFile.WriteString('Themes', 'Skin', Tekst);
+
+ // Color
+ Tekst := IColor[Ini.Color];
+ IniFile.WriteString('Themes', 'Color', Tekst);
+
+ // Record
+ for I := 0 to High(InputDeviceConfig) do begin
+ S := IntToStr(I+1);
+
+ Tekst := InputDeviceConfig[I].Name;
+ IniFile.WriteString('Record', 'DeviceName' + S, Tekst);
+
+ Tekst := IntToStr(InputDeviceConfig[I].Input);
+ IniFile.WriteString('Record', 'Input' + S, Tekst);
+
+ Tekst := IntToStr(InputDeviceConfig[I].ChannelToPlayerMap[0]);
+ IniFile.WriteString('Record', 'ChannelL' + S, Tekst);
+
+ Tekst := IntToStr(InputDeviceConfig[I].ChannelToPlayerMap[1]);
+ IniFile.WriteString('Record', 'ChannelR' + S, Tekst);
+ end;
+
+ //Log.LogError(InttoStr(Length(CardList)) + ' Cards Saved');
+
+ //Advanced Settings
+
+ //LoadAnimation
+ Tekst := ILoadAnimation[Ini.LoadAnimation];
+ IniFile.WriteString('Advanced', 'LoadAnimation', Tekst);
+
+ //EffectSing
+ Tekst := IEffectSing[Ini.EffectSing];
+ IniFile.WriteString('Advanced', 'EffectSing', Tekst);
+
+ //ScreenFade
+ Tekst := IScreenFade[Ini.ScreenFade];
+ IniFile.WriteString('Advanced', 'ScreenFade', Tekst);
+
+ //AskbeforeDel
+ Tekst := IAskbeforeDel[Ini.AskbeforeDel];
+ IniFile.WriteString('Advanced', 'AskbeforeDel', Tekst);
+
+ //OnSongClick
+ Tekst := IOnSongClick[Ini.OnSongClick];
+ IniFile.WriteString('Advanced', 'OnSongClick', Tekst);
+
+ //Line Bonus
+ Tekst := ILineBonus[Ini.LineBonus];
+ IniFile.WriteString('Advanced', 'LineBonus', Tekst);
+
+ //Party Popup
+ Tekst := IPartyPopup[Ini.PartyPopup];
+ IniFile.WriteString('Advanced', 'PartyPopup', Tekst);
+
+ // Joypad
+ Tekst := IJoypad[Ini.Joypad];
+ IniFile.WriteString('Controller', 'Joypad', Tekst);
+
+ IniFile.Free;
+ end;
+end;
+
+procedure TIni.SaveNames;
+var
+ IniFile: TIniFile;
+ I: integer;
+begin
+ //if not FileIsReadOnly(GamePath + 'config.ini') then begin
+ //IniFile := TIniFile.Create(GamePath + 'config.ini');
+ if not FileIsReadOnly(Filename) then begin
+ IniFile := TIniFile.Create(Filename);
+
+ //Name
+ // Templates for Names Mod
+ for I := 1 to 12 do
+ IniFile.WriteString('Name', 'P' + IntToStr(I), Ini.Name[I-1]);
+ for I := 1 to 3 do
+ IniFile.WriteString('NameTeam', 'T' + IntToStr(I), Ini.NameTeam[I-1]);
+ for I := 1 to 12 do
+ IniFile.WriteString('NameTemplate', 'Name' + IntToStr(I), Ini.NameTemplate[I-1]);
+
+ IniFile.Free;
+ end;
+end;
+
+procedure TIni.SaveLevel;
+var
+ IniFile: TIniFile;
+ I: integer;
+begin
+ //if not FileIsReadOnly(GamePath + 'config.ini') then begin
+ //IniFile := TIniFile.Create(GamePath + 'config.ini');
+ if not FileIsReadOnly(Filename) then begin
+ IniFile := TIniFile.Create(Filename);
+
+ // Difficulty
+ IniFile.WriteString('Game', 'Difficulty', IDifficulty[Ini.Difficulty]);
+
+ IniFile.Free;
+ end;
+end;
+
+end.
diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index 901d7370..801a66db 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -195,23 +195,14 @@ begin Log.BenchmarkEnd(1); Log.LogBenchmark('Loading Skin List', 1); -(* - // Sound Card List - Log.BenchmarkStart(1); - Log.LogStatus('Loading Soundcard list', 'Initialization'); - Recording := TRecord.Create; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Soundcard list', 1); -*) - - // Sound (+ fills Sound Card List) + // Sound Log.BenchmarkStart(1); Log.LogStatus('Initialize Sound', 'Initialization'); InitializeSound(); Log.BenchmarkEnd(1); Log.LogBenchmark('Initializing Sound', 1); - // Ini + Paths + // Ini + Paths (depends on Sound) Log.BenchmarkStart(1); Log.LogStatus('Load Ini', 'Initialization'); Ini := TIni.Create; @@ -758,7 +749,7 @@ begin // beat click if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then - AudioPlayback.PlayClick; + AudioPlayback.PlaySound(SoundLib.Click); // debug system on LPT if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then begin @@ -780,7 +771,7 @@ begin if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeatC) then begin // click assist if Ini.ClickAssist = 1 then - AudioPlayback.PlayClick; + AudioPlayback.PlaySound(SoundLib.Click); //LPT_2 := 0; if ParamStr(1) <> '-doublelights' then @@ -871,7 +862,7 @@ begin // Czas.Ton := 27; // gdy moze, to dodaje nute - if (AudioInputProcessor.Sound[CP].SzczytJest) and (Mozna) then begin + if (AudioInputProcessor.Sound[CP].ToneValid) and (Mozna) then begin // operowanie na ostatniej nucie for Pet := 0 to Czesci[0].Czesc[S].HighNut do if (Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1) @@ -880,11 +871,11 @@ begin // to robi, tylko dla pary nut (oryginalnej i gracza) // przesuwanie tonu w odpowiednia game - while (AudioInputProcessor.Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do - AudioInputProcessor.Sound[CP].Ton := AudioInputProcessor.Sound[CP].Ton - 12; + while (AudioInputProcessor.Sound[CP].Tone - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do + AudioInputProcessor.Sound[CP].Tone := AudioInputProcessor.Sound[CP].Tone - 12; - while (AudioInputProcessor.Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do - AudioInputProcessor.Sound[CP].Ton := AudioInputProcessor.Sound[CP].Ton + 12; + while (AudioInputProcessor.Sound[CP].Tone - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do + AudioInputProcessor.Sound[CP].Tone := AudioInputProcessor.Sound[CP].Tone + 12; // Half size Notes Patch NoteHit := false; @@ -894,8 +885,8 @@ begin //if Ini.Difficulty = 2 then Range := 0; Range := 2 - Ini.Difficulty; - if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - AudioInputProcessor.Sound[CP].Ton) <= Range then begin - AudioInputProcessor.Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton; + if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - AudioInputProcessor.Sound[CP].Tone) <= Range then begin + AudioInputProcessor.Sound[CP].Tone := Czesci[0].Czesc[S].Nuta[Pet].Ton; // Half size Notes Patch @@ -936,7 +927,7 @@ begin Nowa := true; // jezeli ostatnia ma ten sam ton if (Player[CP].IlNut > 0 ) - and (Player[CP].Nuta[Player[CP].HighNut].Ton = AudioInputProcessor.Sound[CP].Ton) + and (Player[CP].Nuta[Player[CP].HighNut].Ton = AudioInputProcessor.Sound[CP].Tone) and (Player[CP].Nuta[Player[CP].HighNut].Start + Player[CP].Nuta[Player[CP].HighNut].Dlugosc = Czas.AktBeatD) then Nowa := false; // jezeli jest jakas nowa nuta na sprawdzanym beacie @@ -952,7 +943,7 @@ begin SetLength(Player[CP].Nuta, Player[CP].IlNut); Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD; Player[CP].Nuta[Player[CP].HighNut].Dlugosc := 1; - Player[CP].Nuta[Player[CP].HighNut].Ton := AudioInputProcessor.Sound[CP].Ton; // Ton || TonDokl + Player[CP].Nuta[Player[CP].HighNut].Ton := AudioInputProcessor.Sound[CP].Tone; // Ton || TonDokl Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat; diff --git a/Game/Code/Classes/UMedia_dummy.pas b/Game/Code/Classes/UMedia_dummy.pas index c973512d..cd62dc51 100644 --- a/Game/Code/Classes/UMedia_dummy.pas +++ b/Game/Code/Classes/UMedia_dummy.pas @@ -1,268 +1,206 @@ -unit UMedia_dummy; -{< ############################################################################# -# FFmpeg support for UltraStar deluxe # -# # -# Created by b1indy # -# based on 'An ffmpeg and SDL Tutorial' (http://www.dranger.com/ffmpeg/) # -# # -# http://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg09949.html # -# http://www.nabble.com/file/p11795857/mpegpas01.zip # -# # -############################################################################## } - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -implementation - -uses - SysUtils, - math, - UMusic; - - -var - singleton_dummy : IVideoPlayback; - -type - Tmedia_dummy = class( TInterfacedObject, IVideoPlayback, IVideoVisualization, IAudioPlayback, IAudioInput ) - private - public - constructor create(); - function GetName: String; - - procedure init(); - - function Open( aFileName : string): boolean; // true if succeed - procedure Close; - - procedure Play; - procedure Pause; - procedure Stop; - - procedure SetPosition(Time: real); - function GetPosition: real; - - procedure GetFrame(Time: Extended); - procedure DrawGL(Screen: integer); - - // IAudioInput - procedure InitializeRecord; - procedure CaptureStart; - procedure CaptureStop; - procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); - procedure StopCard(Card: byte); - function GetFFTData: TFFTData; - function GetPCMData(var data: TPCMData): Cardinal; - - // IAudioPlayback - procedure InitializePlayback; - procedure SetVolume(Volume: integer); - procedure SetMusicVolume(Volume: integer); - procedure SetLoop(Enabled: boolean); - procedure Rewind; - - function Finished: boolean; - function Length: real; - - procedure PlayStart; - procedure PlayBack; - procedure PlaySwoosh; - procedure PlayChange; - procedure PlayOption; - procedure PlayClick; - procedure PlayDrum; - procedure PlayHihat; - procedure PlayClap; - procedure PlayShuffle; - procedure StopShuffle; - - function LoadCustomSound(const Filename: String): Cardinal; - procedure PlayCustomSound(const Index: Cardinal ); - - end; - - - -function Tmedia_dummy.GetName: String; -begin - result := 'dummy'; -end; - - -procedure Tmedia_dummy.GetFrame(Time: Extended); -begin -end; - -procedure Tmedia_dummy.DrawGL(Screen: integer); -begin -end; - -constructor Tmedia_dummy.create(); -begin -end; - -procedure Tmedia_dummy.init(); -begin -end; - - -function Tmedia_dummy.Open( aFileName : string): boolean; // true if succeed -begin - result := false; -end; - -procedure Tmedia_dummy.Close; -begin -end; - -procedure Tmedia_dummy.Play; -begin -end; - -procedure Tmedia_dummy.Pause; -begin -end; - -procedure Tmedia_dummy.Stop; -begin -end; - -procedure Tmedia_dummy.SetPosition(Time: real); -begin -end; - -function Tmedia_dummy.getPosition: real; -begin - result := 0; -end; - -// IAudioInput -procedure Tmedia_dummy.InitializeRecord; -begin -end; - -procedure Tmedia_dummy.CaptureStart; -begin -end; - -procedure Tmedia_dummy.CaptureStop; -begin -end; - -procedure Tmedia_dummy.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); -begin -end; - -procedure Tmedia_dummy.StopCard(Card: byte); -begin -end; - -function Tmedia_dummy.GetFFTData: TFFTData; -var data: TFFTData; -begin - result := data; -end; - -function Tmedia_dummy.GetPCMData(var data: TPCMData): Cardinal; -begin - result := 0; -end; - -// IAudioPlayback -procedure Tmedia_dummy.InitializePlayback; -begin -end; - -procedure Tmedia_dummy.SetVolume(Volume: integer); -begin -end; - -procedure Tmedia_dummy.SetMusicVolume(Volume: integer); -begin -end; - -procedure Tmedia_dummy.SetLoop(Enabled: boolean); -begin -end; - -procedure Tmedia_dummy.Rewind; -begin -end; - -function Tmedia_dummy.Finished: boolean; -begin - result := false; -end; - -function Tmedia_dummy.Length: real; -begin - Result := 60; -end; - -procedure Tmedia_dummy.PlayStart; -begin -end; - -procedure Tmedia_dummy.PlayBack; -begin -end; - -procedure Tmedia_dummy.PlaySwoosh; -begin -end; - -procedure Tmedia_dummy.PlayChange; -begin -end; - -procedure Tmedia_dummy.PlayOption; -begin -end; - -procedure Tmedia_dummy.PlayClick; -begin -end; - -procedure Tmedia_dummy.PlayDrum; -begin -end; - -procedure Tmedia_dummy.PlayHihat; -begin -end; - -procedure Tmedia_dummy.PlayClap; -begin -end; - -procedure Tmedia_dummy.PlayShuffle; -begin -end; - -procedure Tmedia_dummy.StopShuffle; -begin -end; - -function Tmedia_dummy.LoadCustomSound(const Filename: String): Cardinal; -begin - result := 0; -end; - -procedure Tmedia_dummy.PlayCustomSound(const Index: Cardinal ); -begin -end; - -initialization - singleton_dummy := Tmedia_dummy.create(); - AudioManager.add( singleton_dummy ); - -finalization - AudioManager.Remove( singleton_dummy ); - -end. +unit UMedia_dummy;
+{< #############################################################################
+# FFmpeg support for UltraStar deluxe #
+# #
+# Created by b1indy #
+# based on 'An ffmpeg and SDL Tutorial' (http://www.dranger.com/ffmpeg/) #
+# #
+# http://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg09949.html #
+# http://www.nabble.com/file/p11795857/mpegpas01.zip #
+# #
+############################################################################## }
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+implementation
+
+uses
+ SysUtils,
+ math,
+ UMusic;
+
+
+var
+ singleton_dummy : IVideoPlayback;
+
+type
+ Tmedia_dummy = class( TInterfacedObject, IVideoPlayback, IVideoVisualization, IAudioPlayback, IAudioInput )
+ private
+ public
+ constructor create();
+ function GetName: String;
+
+ procedure init();
+
+ function Open( aFileName : string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ procedure GetFrame(Time: Extended);
+ procedure DrawGL(Screen: integer);
+
+ // IAudioInput
+ function InitializeRecord: boolean;
+ procedure CaptureStart;
+ procedure CaptureStop;
+ procedure GetFFTData(var data: TFFTData);
+ function GetPCMData(var data: TPCMData): Cardinal;
+
+ // IAudioPlayback
+ function InitializePlayback: boolean;
+ procedure SetVolume(Volume: integer);
+ procedure SetMusicVolume(Volume: integer);
+ procedure SetLoop(Enabled: boolean);
+ procedure Rewind;
+
+ function Finished: boolean;
+ function Length: real;
+
+ function OpenSound(const Filename: String): TAudioPlaybackStream;
+ procedure PlaySound(stream: TAudioPlaybackStream);
+ procedure StopSound(stream: TAudioPlaybackStream);
+ end;
+
+
+
+function Tmedia_dummy.GetName: String;
+begin
+ result := 'dummy';
+end;
+
+
+procedure Tmedia_dummy.GetFrame(Time: Extended);
+begin
+end;
+
+procedure Tmedia_dummy.DrawGL(Screen: integer);
+begin
+end;
+
+constructor Tmedia_dummy.create();
+begin
+end;
+
+procedure Tmedia_dummy.init();
+begin
+end;
+
+
+function Tmedia_dummy.Open( aFileName : string): boolean; // true if succeed
+begin
+ result := false;
+end;
+
+procedure Tmedia_dummy.Close;
+begin
+end;
+
+procedure Tmedia_dummy.Play;
+begin
+end;
+
+procedure Tmedia_dummy.Pause;
+begin
+end;
+
+procedure Tmedia_dummy.Stop;
+begin
+end;
+
+procedure Tmedia_dummy.SetPosition(Time: real);
+begin
+end;
+
+function Tmedia_dummy.getPosition: real;
+begin
+ result := 0;
+end;
+
+// IAudioInput
+function Tmedia_dummy.InitializeRecord: boolean;
+begin
+ result := true;
+end;
+
+procedure Tmedia_dummy.CaptureStart;
+begin
+end;
+
+procedure Tmedia_dummy.CaptureStop;
+begin
+end;
+
+procedure Tmedia_dummy.GetFFTData(var data: TFFTData);
+begin
+end;
+
+function Tmedia_dummy.GetPCMData(var data: TPCMData): Cardinal;
+begin
+ result := 0;
+end;
+
+// IAudioPlayback
+function Tmedia_dummy.InitializePlayback: boolean;
+begin
+ result := true;
+end;
+
+procedure Tmedia_dummy.SetVolume(Volume: integer);
+begin
+end;
+
+procedure Tmedia_dummy.SetMusicVolume(Volume: integer);
+begin
+end;
+
+procedure Tmedia_dummy.SetLoop(Enabled: boolean);
+begin
+end;
+
+procedure Tmedia_dummy.Rewind;
+begin
+end;
+
+function Tmedia_dummy.Finished: boolean;
+begin
+ result := false;
+end;
+
+function Tmedia_dummy.Length: real;
+begin
+ Result := 60;
+end;
+
+function Tmedia_dummy.OpenSound(const Filename: String): TAudioPlaybackStream;
+begin
+ result := nil;
+end;
+
+procedure Tmedia_dummy.PlaySound(stream: TAudioPlaybackStream);
+begin
+end;
+
+procedure Tmedia_dummy.StopSound(stream: TAudioPlaybackStream);
+begin
+end;
+
+initialization
+ singleton_dummy := Tmedia_dummy.create();
+ AudioManager.add( singleton_dummy );
+
+finalization
+ AudioManager.Remove( singleton_dummy );
+
+end.
diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index a7f1918f..27ab86e1 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -1,423 +1,492 @@ -unit UMusic; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -uses Classes ; - -type - TMuzyka = record - Path: string; - Start: integer; // start of song in ms - IlNut: integer; - DlugoscNut: integer; - end; - - PLine = ^TLine; - TLine = record - Start: integer; - StartNote: integer; - Lyric: string; - LyricWidth: real; - Koniec: integer; - BaseNote: integer; - HighNut: integer; - IlNut: integer; - TotalNotes: integer; - Nuta: array of record - Color: integer; - Start: integer; - Dlugosc: integer; - Ton: integer; - TonGamy: integer; - Tekst: string; - FreeStyle: boolean; - Wartosc: integer; // zwykla nuta x1, zlota nuta x2 - end; - end; - ALine = array of TLine; - - TCzesci = record - Akt: integer; // aktualna czesc utworu do rysowania - High: integer; - Ilosc: integer; - Resolution: integer; - NotesGAP: integer; - Wartosc: integer; - Czesc: ALine; - end; - - TCzas = record // wszystko, co dotyczy aktualnej klatki - OldBeat: integer; // poprzednio wykryty beat w utworze - AktBeat: integer; // aktualny beat w utworze - MidBeat: real; // dokladny AktBeat - - // now we use this for super synchronization! - // only used when analyzing voice - OldBeatD: integer; // poprzednio wykryty beat w utworze - AktBeatD: integer; // aktualny beat w utworze - MidBeatD: real; // dokladny AktBeatD - FracBeatD: real; // fractional part of MidBeatD - - // we use this for audiable clicks - OldBeatC: integer; // poprzednio wykryty beat w utworze - AktBeatC: integer; // aktualny beat w utworze - MidBeatC: real; // dokladny AktBeatC - FracBeatC: real; // fractional part of MidBeatC - - - OldCzesc: integer; // poprzednio wyswietlana czesc - // akt jest w czesci.akt - - Teraz: real; // aktualny czas w utworze - Razem: real; // caly czas utworu - end; - - TSoundCard = record - Name: string; - Source: array of string; - end; - -type - TFFTData = array[0..256] of Single; - - TPCMStereoSample = array[0..1] of Smallint; - TPCMData = array[0..511] of TPCMStereoSample; - -type - TStreamStatus = (sStopped, sPlaying, sPaused); -const - StreamStatusStr: array[TStreamStatus] of string = ('Stopped', 'Playing', 'Paused'); - -type - TAudioProcessingStream = class - public - procedure Close(); virtual; abstract; - end; - - TAudioPlaybackStream = class(TAudioProcessingStream) - protected - function GetLoop(): boolean; virtual; abstract; - procedure SetLoop(Enabled: boolean); virtual; abstract; - function GetLength(): real; virtual; abstract; - function GetStatus(): TStreamStatus; virtual; abstract; - public - procedure Play(); virtual; abstract; - procedure Pause(); virtual; abstract; - procedure Stop(); virtual; abstract; - - property Loop: boolean READ GetLoop WRITE SetLoop; - property Length: real READ GetLength; - property Status: TStreamStatus READ GetStatus; - end; - - (* - TAudioMixerStream = class(TAudioProcessingStream) - procedure AddStream(stream: TAudioProcessingStream); - procedure RemoveStream(stream: TAudioProcessingStream); - procedure SetMasterVolume(volume: cardinal); - function GetMasterVolume(): cardinal; - procedure SetStreamVolume(stream: TAudioProcessingStream; volume: cardinal); - function GetStreamVolume(stream: TAudioProcessingStream): cardinal; - end; - *) - - TAudioDecodeStream = class(TAudioProcessingStream) - protected - function GetLength(): real; virtual; abstract; - function GetChannelCount(): cardinal; virtual; abstract; - function GetSampleRate(): cardinal; virtual; abstract; - function GetPosition(): real; virtual; abstract; - procedure SetPosition(Time: real); virtual; abstract; - function IsEOF(): boolean; virtual; abstract; - public - function ReadData(Buffer: PChar; BufSize: integer): integer; virtual; abstract; - - property Length: real READ GetLength; - property ChannelCount: cardinal READ GetChannelCount; - property SampleRate: cardinal READ GetSampleRate; - property Position: real READ GetPosition WRITE SetPosition; - property EOF: boolean READ IsEOF; - end; - -type - TCustomSoundEntry = record - Filename : String; - Stream : TAudioPlaybackStream; - end; - -type - IGenericPlayback = Interface - ['{63A5EBC3-3F4D-4F23-8DFB-B5165FCE33DD}'] - function GetName: String; - - function Open(Filename: string): boolean; // true if succeed - procedure Close; - - procedure Play; - procedure Pause; - procedure Stop; - - procedure SetPosition(Time: real); - function GetPosition: real; - - property Position : real READ GetPosition WRITE SetPosition; - end; - - IVideoPlayback = Interface( IGenericPlayback ) - ['{3574C40C-28AE-4201-B3D1-3D1F0759B131}'] - procedure init(); - - procedure GetFrame(Time: Extended); // WANT TO RENAME THESE TO BE MORE GENERIC - procedure DrawGL(Screen: integer); // WANT TO RENAME THESE TO BE MORE GENERIC - - end; - - IVideoVisualization = Interface( IVideoPlayback ) - ['{5AC17D60-B34D-478D-B632-EB00D4078017}'] - end; - - IAudioPlayback = Interface( IGenericPlayback ) - ['{E4AE0B40-3C21-4DC5-847C-20A87E0DFB96}'] - procedure InitializePlayback; - procedure SetVolume(Volume: integer); - procedure SetMusicVolume(Volume: integer); - procedure SetLoop(Enabled: boolean); - - procedure Rewind; - function Finished: boolean; - function Length: real; - - procedure PlayStart; - procedure PlayBack; - procedure PlaySwoosh; - procedure PlayChange; - procedure PlayOption; - procedure PlayClick; - procedure PlayDrum; - procedure PlayHihat; - procedure PlayClap; - procedure PlayShuffle; - procedure StopShuffle; - - //Custom Sounds - function LoadCustomSound(const Filename: String): Cardinal; - procedure PlayCustomSound(const Index: Cardinal ); - - //Equalizer - function GetFFTData: TFFTData; - - // Interface for Visualizer - function GetPCMData(var data: TPCMData): Cardinal; - end; - - IGenericDecoder = Interface - ['{557B0E9A-604D-47E4-B826-13769F3E10B7}'] - function InitializeDecoder(): boolean; - //function IsSupported(const Filename: string): boolean; - end; - - (* - IVideoDecoder = Interface( IGenericDecoder ) - ['{2F184B2B-FE69-44D5-9031-0A2462391DCA}'] - function Open(const Filename: string): TVideoDecodeStream; - end; - *) - - IAudioDecoder = Interface( IGenericDecoder ) - ['{AB47B1B6-2AA9-4410-BF8C-EC79561B5478}'] - function Open(const Filename: string): TAudioDecodeStream; - end; - - IAudioInput = Interface - ['{A5C8DA92-2A0C-4AB2-849B-2F7448C6003A}'] - function GetName: String; - procedure InitializeRecord; - - procedure CaptureStart; - procedure CaptureStop; - end; - - -var // TODO : JB --- THESE SHOULD NOT BE GLOBAL - // muzyka - Muzyka: TMuzyka; - - // czesci z nutami; - Czesci: array of TCzesci; - - // czas - Czas: TCzas; - - -procedure InitializeSound; - -function Visualization(): IVideoPlayback; -function VideoPlayback(): IVideoPlayback; -function AudioPlayback(): IAudioPlayback; -function AudioInput(): IAudioInput; -function AudioDecoder(): IAudioDecoder; - -function AudioManager: TInterfaceList; - - -implementation - -uses - sysutils, - UCommandLine; -// uLog; - -var - singleton_VideoPlayback : IVideoPlayback = nil; - singleton_Visualization : IVideoPlayback = nil; - singleton_AudioPlayback : IAudioPlayback = nil; - singleton_AudioInput : IAudioInput = nil; - singleton_AudioDecoder : IAudioDecoder = nil; - - singleton_AudioManager : TInterfaceList = nil; - - -function AudioManager: TInterfaceList; -begin - if singleton_AudioManager = nil then - singleton_AudioManager := TInterfaceList.Create(); - - Result := singleton_AudioManager; -end; //CompressionPluginManager - - -function VideoPlayback(): IVideoPlayback; -begin - result := singleton_VideoPlayback; -end; - -function Visualization(): IVideoPlayback; -begin - result := singleton_Visualization; -end; - -function AudioPlayback(): IAudioPlayback; -begin - result := singleton_AudioPlayback; -end; - -function AudioInput(): IAudioInput; -begin - result := singleton_AudioInput; -end; - -function AudioDecoder(): IAudioDecoder; -begin - result := singleton_AudioDecoder; -end; - -procedure InitializeSound; -var - lTmpInterface : IInterface; - iCount : Integer; -begin - lTmpInterface := nil; - - singleton_AudioPlayback := nil; - singleton_AudioInput := nil; - singleton_AudioDecoder := nil; - singleton_VideoPlayback := nil; - singleton_Visualization := nil; - - for iCount := 0 to AudioManager.Count - 1 do - begin - if assigned( AudioManager[iCount] ) then - begin - // if this interface is a Playback, then set it as the default used - - if ( AudioManager[iCount].QueryInterface( IAudioPlayback, lTmpInterface ) = 0 ) AND - ( true ) then - begin - singleton_AudioPlayback := IAudioPlayback( lTmpInterface ); - end; - - // if this interface is a Input, then set it as the default used - if ( AudioManager[iCount].QueryInterface( IAudioInput, lTmpInterface ) = 0 ) AND - ( true ) then - begin - singleton_AudioInput := IAudioInput( lTmpInterface ); - end; - - // if this interface is a Decoder, then set it as the default used - if ( AudioManager[iCount].QueryInterface( IAudioDecoder, lTmpInterface ) = 0 ) AND - ( true ) then - begin - singleton_AudioDecoder := IAudioDecoder( lTmpInterface ); - end; - - // if this interface is a Input, then set it as the default used - if ( AudioManager[iCount].QueryInterface( IVideoPlayback, lTmpInterface ) = 0 ) AND - ( true ) then - begin - singleton_VideoPlayback := IVideoPlayback( lTmpInterface ); - end; - - if ( AudioManager[iCount].QueryInterface( IVideoVisualization, lTmpInterface ) = 0 ) AND - ( true ) then - begin - singleton_Visualization := IVideoPlayback( lTmpInterface ); - end; - - end; - end; - - - - if VideoPlayback <> nil then - begin - end; - - if AudioDecoder <> nil then - begin - AudioDecoder.InitializeDecoder; - end; - - if AudioPlayback <> nil then - begin - AudioPlayback.InitializePlayback; - end; - - if AudioInput <> nil then - begin - AudioInput.InitializeRecord; - end; - - if FindCmdLineSwitch( cMediaInterfaces ) then - begin - writeln( '' ); - writeln( '--------------------------------------------------------------' ); - writeln( ' In-use Media Interfaces ' ); - writeln( '--------------------------------------------------------------' ); - writeln( 'Registered Audio Playback Interface : ' + AudioPlayback.GetName ); - writeln( 'Registered Audio Input Interface : ' + AudioInput.GetName ); - writeln( 'Registered Video Playback Interface : ' + VideoPlayback.GetName ); - writeln( 'Registered Visualization Interface : ' + Visualization.GetName ); - writeln( '--------------------------------------------------------------' ); - writeln( '' ); - - halt; - end; -end; - -initialization -begin - singleton_AudioManager := TInterfaceList.Create(); - -end; - -finalization - singleton_AudioManager.clear; - FreeAndNil( singleton_AudioManager ); - -end. +unit UMusic;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ Classes;
+
+type
+ TNoteType = (ntFreestyle, ntNormal, ntGolden);
+
+ //http://paste.ubuntu-nl.org/51892/
+
+ TMuzyka = record // (TODO: rename to TMusic/TMelody?)
+ Path: string;
+ Start: integer; // start of song in ms
+ IlNut: integer; // (TODO: Il = tone, Nut(a) = Note)
+ DlugoscNut: integer; // (TODO: Dlugosc = length, Nut(a) = Note)
+ end;
+
+ PLine = ^TLine;
+ TLine = record // (TODO: rename to TSentence?)
+ Start: integer;
+ StartNote: integer;
+ Lyric: string;
+ LyricWidth: real;
+ Koniec: integer; // (TODO: rename to End_/Ending?)
+ BaseNote: integer;
+ HighNut: integer; // (TODO: rename to HighNote)
+ IlNut: integer; // (TODO: Il = tone, Nut(a) = Note)
+ TotalNotes: integer;
+ Nuta: array of record // (TODO: rename to Note)
+ Color: integer;
+ Start: integer;
+ Dlugosc: integer; // (TODO: rename to Length)
+ Ton: integer; // full range tone (TODO: rename to Tone)
+ TonGamy: integer; // tone unified to one octave (TODO: rename to something meaningful, ToneGamus)
+ Tekst: string; // (TODO: rename to Text)
+ FreeStyle: boolean;
+ Wartosc: integer; // normal-note: 1, golden-note: 2 (TODO: wartosc=value, rename to Type_ or Kind?)
+ end;
+ end;
+ ALine = array of TLine; // (TODO: rename to TLineArray)
+
+ // (TCzesci = TSentences)
+ TCzesci = record
+ Akt: integer; // for drawing of current line (Akt = Current)
+ High: integer;
+ Ilosc: integer; // (TODO: Ilosc = Number/Count)
+ Resolution: integer;
+ NotesGAP: integer;
+ Wartosc: integer; // TODO: rename (wartosc=value)
+ Czesc: ALine; // TODO: rename to Sentence or Line
+ end;
+
+ // (TODO: rename TCzas to something like T(Line/Sentence)Time/TLinePosition/TLineState)
+ // (Czas = time)
+ TCzas = record // all that concerns the current frames
+ OldBeat: integer; // previous discovered beat
+ AktBeat: integer; // current beat (TODO: rename)
+ MidBeat: real; // like AktBeat
+
+ // now we use this for super synchronization!
+ // only used when analyzing voice
+ OldBeatD: integer; // previous discovered beat
+ AktBeatD: integer; // current beat (TODO: rename)
+ MidBeatD: real; // like AktBeatD
+ FracBeatD: real; // fractional part of MidBeatD
+
+ // we use this for audible clicks
+ OldBeatC: integer; // previous discovered beat
+ AktBeatC: integer; // current beat (TODO: rename)
+ MidBeatC: real; // like AktBeatC
+ FracBeatC: real; // fractional part of MidBeatC
+
+
+ OldCzesc: integer; // previous displayed sentence (Czesc = part (here: sentence/line))
+
+ Teraz: real; // (TODO: Teraz = current time)
+ Razem: real; // (TODO: Razem = total time)
+ end;
+
+
+type
+ TFFTData = array[0..255] of Single;
+
+ TPCMStereoSample = array[0..1] of Smallint;
+ TPCMData = array[0..511] of TPCMStereoSample;
+
+type
+ TStreamStatus = (ssStopped, ssPlaying, ssPaused, ssBlocked, ssUnknown);
+const
+ StreamStatusStr: array[TStreamStatus] of string =
+ ('Stopped', 'Playing', 'Paused', 'Blocked', 'Unknown');
+
+type
+ TAudioSampleFormat = (
+ asfU8, asfS8, // unsigned/signed 8 bits
+ asfU16LSB, asfS16LSB, // unsigned/signed 16 bits (endianness: LSB)
+ asfU16MSB, asfS16MSB, // unsigned/signed 16 bits (endianness: MSB)
+ asfU16, asfS16, // unsigned/signed 16 bits (endianness: System)
+ asfS24, // signed 24 bits (endianness: System)
+ asfS32, // signed 32 bits (endianness: System)
+ asfFloat // float
+ );
+
+ TAudioFormatInfo = record
+ Channels: byte;
+ SampleRate: integer;
+ Format: TAudioSampleFormat;
+ end;
+
+type
+ TAudioProcessingStream = class
+ public
+ procedure Close(); virtual; abstract;
+ end;
+
+ TAudioPlaybackStream = class(TAudioProcessingStream)
+ protected
+ function GetLoop(): boolean; virtual; abstract;
+ procedure SetLoop(Enabled: boolean); virtual; abstract;
+ function GetLength(): real; virtual; abstract;
+ function GetStatus(): TStreamStatus; virtual; abstract;
+ function GetVolume(): integer; virtual; abstract;
+ procedure SetVolume(volume: integer); virtual; abstract;
+ public
+ procedure Play(); virtual; abstract;
+ procedure Pause(); virtual; abstract;
+ procedure Stop(); virtual; abstract;
+
+ property Loop: boolean READ GetLoop WRITE SetLoop;
+ property Length: real READ GetLength;
+ property Status: TStreamStatus READ GetStatus;
+ property Volume: integer READ GetVolume WRITE SetVolume;
+ end;
+
+ (*
+ TAudioMixerStream = class(TAudioProcessingStream)
+ procedure AddStream(stream: TAudioProcessingStream);
+ procedure RemoveStream(stream: TAudioProcessingStream);
+ procedure SetMasterVolume(volume: cardinal);
+ function GetMasterVolume(): cardinal;
+ procedure SetStreamVolume(stream: TAudioProcessingStream; volume: cardinal);
+ function GetStreamVolume(stream: TAudioProcessingStream): cardinal;
+ end;
+ *)
+
+ TAudioDecodeStream = class(TAudioProcessingStream)
+ protected
+ function GetLength(): real; virtual; abstract;
+ function GetPosition(): real; virtual; abstract;
+ procedure SetPosition(Time: real); virtual; abstract;
+ function IsEOF(): boolean; virtual; abstract;
+ public
+ function ReadData(Buffer: PChar; BufSize: integer): integer; virtual; abstract;
+ function GetAudioFormatInfo(): TAudioFormatInfo; virtual; abstract;
+
+ property Length: real READ GetLength;
+ property Position: real READ GetPosition WRITE SetPosition;
+ property EOF: boolean READ IsEOF;
+ end;
+
+type
+ IGenericPlayback = Interface
+ ['{63A5EBC3-3F4D-4F23-8DFB-B5165FCE33DD}']
+ function GetName: String;
+
+ function Open(Filename: string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure SetPosition(Time: real);
+ function GetPosition: real;
+
+ property Position : real READ GetPosition WRITE SetPosition;
+ end;
+
+ IVideoPlayback = Interface( IGenericPlayback )
+ ['{3574C40C-28AE-4201-B3D1-3D1F0759B131}']
+ procedure init();
+
+ procedure GetFrame(Time: Extended); // WANT TO RENAME THESE TO BE MORE GENERIC
+ procedure DrawGL(Screen: integer); // WANT TO RENAME THESE TO BE MORE GENERIC
+
+ end;
+
+ IVideoVisualization = Interface( IVideoPlayback )
+ ['{5AC17D60-B34D-478D-B632-EB00D4078017}']
+ end;
+
+ IAudioPlayback = Interface( IGenericPlayback )
+ ['{E4AE0B40-3C21-4DC5-847C-20A87E0DFB96}']
+ function InitializePlayback: boolean;
+ procedure SetVolume(Volume: integer);
+ procedure SetMusicVolume(Volume: integer);
+ procedure SetLoop(Enabled: boolean);
+
+ procedure Rewind;
+ function Finished: boolean;
+ function Length: real;
+
+ // Sounds
+ function OpenSound(const Filename: String): TAudioPlaybackStream;
+ procedure PlaySound(stream: TAudioPlaybackStream);
+ procedure StopSound(stream: TAudioPlaybackStream);
+
+ // Equalizer
+ procedure GetFFTData(var data: TFFTData);
+
+ // Interface for Visualizer
+ function GetPCMData(var data: TPCMData): Cardinal;
+ end;
+
+ IGenericDecoder = Interface
+ ['{557B0E9A-604D-47E4-B826-13769F3E10B7}']
+ function InitializeDecoder(): boolean;
+ //function IsSupported(const Filename: string): boolean;
+ end;
+
+ (*
+ IVideoDecoder = Interface( IGenericDecoder )
+ ['{2F184B2B-FE69-44D5-9031-0A2462391DCA}']
+ function Open(const Filename: string): TVideoDecodeStream;
+ end;
+ *)
+
+ IAudioDecoder = Interface( IGenericDecoder )
+ ['{AB47B1B6-2AA9-4410-BF8C-EC79561B5478}']
+ function Open(const Filename: string): TAudioDecodeStream;
+ end;
+
+ IAudioInput = Interface
+ ['{A5C8DA92-2A0C-4AB2-849B-2F7448C6003A}']
+ function GetName: String;
+ function InitializeRecord: boolean;
+
+ procedure CaptureStart;
+ procedure CaptureStop;
+ end;
+
+type
+ TSoundLibrary = class
+ public
+ Start: TAudioPlaybackStream;
+ Back: TAudioPlaybackStream;
+ Swoosh: TAudioPlaybackStream;
+ Change: TAudioPlaybackStream;
+ Option: TAudioPlaybackStream;
+ Click: TAudioPlaybackStream;
+ Drum: TAudioPlaybackStream;
+ Hihat: TAudioPlaybackStream;
+ Clap: TAudioPlaybackStream;
+ Shuffle: TAudioPlaybackStream;
+
+ constructor Create();
+ destructor Destroy(); override;
+ end;
+
+var // TODO : JB --- THESE SHOULD NOT BE GLOBAL
+ // music
+ Muzyka: TMuzyka; // TODO: rename
+
+ // czesci z nutami;
+ Czesci: array of TCzesci; // TODO: rename to Sentences/Lines
+
+ // czas
+ Czas: TCzas; // TODO: rename
+
+ SoundLib: TSoundLibrary;
+
+
+procedure InitializeSound;
+
+function Visualization(): IVideoPlayback;
+function VideoPlayback(): IVideoPlayback;
+function AudioPlayback(): IAudioPlayback;
+function AudioInput(): IAudioInput;
+function AudioDecoder(): IAudioDecoder;
+
+function AudioManager: TInterfaceList;
+
+
+implementation
+
+uses
+ sysutils,
+ UMain,
+ UCommandLine;
+// uLog;
+
+var
+ singleton_VideoPlayback : IVideoPlayback = nil;
+ singleton_Visualization : IVideoPlayback = nil;
+ singleton_AudioPlayback : IAudioPlayback = nil;
+ singleton_AudioInput : IAudioInput = nil;
+ singleton_AudioDecoder : IAudioDecoder = nil;
+
+ singleton_AudioManager : TInterfaceList = nil;
+
+
+function AudioManager: TInterfaceList;
+begin
+ if singleton_AudioManager = nil then
+ singleton_AudioManager := TInterfaceList.Create();
+
+ Result := singleton_AudioManager;
+end; //CompressionPluginManager
+
+
+function VideoPlayback(): IVideoPlayback;
+begin
+ result := singleton_VideoPlayback;
+end;
+
+function Visualization(): IVideoPlayback;
+begin
+ result := singleton_Visualization;
+end;
+
+function AudioPlayback(): IAudioPlayback;
+begin
+ result := singleton_AudioPlayback;
+end;
+
+function AudioInput(): IAudioInput;
+begin
+ result := singleton_AudioInput;
+end;
+
+function AudioDecoder(): IAudioDecoder;
+begin
+ result := singleton_AudioDecoder;
+end;
+
+procedure InitializeSound;
+var
+ lTmpInterface : IInterface;
+ iCount : Integer;
+begin
+ lTmpInterface := nil;
+
+ singleton_AudioPlayback := nil;
+ singleton_AudioInput := nil;
+ singleton_AudioDecoder := nil;
+ singleton_VideoPlayback := nil;
+ singleton_Visualization := nil;
+
+ for iCount := 0 to AudioManager.Count - 1 do
+ begin
+ if assigned( AudioManager[iCount] ) then
+ begin
+ // if this interface is a Playback, then set it as the default used
+
+ if ( AudioManager[iCount].QueryInterface( IAudioPlayback, lTmpInterface ) = 0 ) AND
+ ( true ) then
+ begin
+ singleton_AudioPlayback := IAudioPlayback( lTmpInterface );
+ end;
+
+ // if this interface is a Input, then set it as the default used
+ if ( AudioManager[iCount].QueryInterface( IAudioInput, lTmpInterface ) = 0 ) AND
+ ( true ) then
+ begin
+ singleton_AudioInput := IAudioInput( lTmpInterface );
+ end;
+
+ // if this interface is a Decoder, then set it as the default used
+ if ( AudioManager[iCount].QueryInterface( IAudioDecoder, lTmpInterface ) = 0 ) AND
+ ( true ) then
+ begin
+ singleton_AudioDecoder := IAudioDecoder( lTmpInterface );
+ end;
+
+ // if this interface is a Input, then set it as the default used
+ if ( AudioManager[iCount].QueryInterface( IVideoPlayback, lTmpInterface ) = 0 ) AND
+ ( true ) then
+ begin
+ singleton_VideoPlayback := IVideoPlayback( lTmpInterface );
+ end;
+
+ if ( AudioManager[iCount].QueryInterface( IVideoVisualization, lTmpInterface ) = 0 ) AND
+ ( true ) then
+ begin
+ singleton_Visualization := IVideoPlayback( lTmpInterface );
+ end;
+
+ end;
+ end;
+
+
+
+ if VideoPlayback <> nil then
+ begin
+ end;
+
+ if AudioDecoder <> nil then
+ begin
+ AudioDecoder.InitializeDecoder;
+ end;
+
+ if AudioPlayback <> nil then
+ begin
+ AudioPlayback.InitializePlayback;
+ end;
+
+ if AudioInput <> nil then
+ begin
+ AudioInput.InitializeRecord;
+ end;
+
+ // Load in-game sounds
+ SoundLib := TSoundLibrary.Create;
+
+ if FindCmdLineSwitch( cMediaInterfaces ) then
+ begin
+ writeln( '' );
+ writeln( '--------------------------------------------------------------' );
+ writeln( ' In-use Media Interfaces ' );
+ writeln( '--------------------------------------------------------------' );
+ writeln( 'Registered Audio Playback Interface : ' + AudioPlayback.GetName );
+ writeln( 'Registered Audio Input Interface : ' + AudioInput.GetName );
+ writeln( 'Registered Video Playback Interface : ' + VideoPlayback.GetName );
+ writeln( 'Registered Visualization Interface : ' + Visualization.GetName );
+ writeln( '--------------------------------------------------------------' );
+ writeln( '' );
+
+ halt;
+ end;
+end;
+
+constructor TSoundLibrary.Create();
+begin
+ //Log.LogStatus('Loading Sounds', 'Music Initialize');
+
+ //Log.BenchmarkStart(4);
+
+ Start := AudioPlayback.OpenSound(SoundPath + 'Common start.mp3');
+ (*
+ Back := AudioPlayback.OpenSound(SoundPath + 'Common back.mp3');
+ Swoosh := AudioPlayback.OpenSound(SoundPath + 'menu swoosh.mp3');
+ Change := AudioPlayback.OpenSound(SoundPath + 'select music change music 50.mp3');
+ Option := AudioPlayback.OpenSound(SoundPath + 'option change col.mp3');
+ Click := AudioPlayback.OpenSound(SoundPath + 'rimshot022b.mp3');
+ *)
+
+ //Drum := AudioPlayback.OpenSound(SoundPath + 'bassdrumhard076b.mp3');
+ //Hihat := AudioPlayback.OpenSound(SoundPath + 'hihatclosed068b.mp3');
+ //Clap := AudioPlayback.OpenSound(SoundPath + 'claps050b.mp3');
+
+ //Shuffle := AudioPlayback.OpenSound(SoundPath + 'Shuffle.mp3');
+
+ //Log.BenchmarkEnd(4);
+ //Log.LogBenchmark('--> Loading Sounds', 4);
+end;
+
+destructor TSoundLibrary.Destroy();
+begin
+ Start.Free;
+ Back.Free;
+ Swoosh.Free;
+ Change.Free;
+ Option.Free;
+ Click.Free;
+
+ //Drum.Free;
+ //Hihat.Free;
+ //Clap.Free;
+
+ //Shuffle.Free;
+end;
+
+
+initialization
+begin
+ singleton_AudioManager := TInterfaceList.Create();
+
+end;
+
+finalization
+ singleton_AudioManager.clear;
+ FreeAndNil( singleton_AudioManager );
+
+end.
diff --git a/Game/Code/Classes/URecord.pas b/Game/Code/Classes/URecord.pas index ab351f6e..8ae0978a 100644 --- a/Game/Code/Classes/URecord.pas +++ b/Game/Code/Classes/URecord.pas @@ -1,325 +1,535 @@ -unit URecord; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -uses Classes, - Math, - SysUtils, - UCommon, - UMusic, - UIni; - -// http://www.poltran.com - -type - TSound = class - BufferNew: TMemoryStream; // buffer for newest sample - BufferArray: array[1..4096] of smallint; // (Signal) newest 4096 samples - BufferLong: array of TMemoryStream; // full buffer - - Num: integer; - n: integer; // length of Signal to analyze - - // pitch detection - SzczytJest: boolean; // czy jest szczyt - pivot : integer; // Position of summit (top) on horizontal pivot - TonDokl: real; // ton aktualnego szczytu - Ton: integer; // ton bez ulamka - TonGamy: integer; // ton w gamie. wartosci: 0-11 - Skala: real; // skala FFT - - // procedures - procedure ProcessNewBuffer; - procedure AnalyzeBuffer; // use to analyze sound from buffers to get new pitch - procedure AnalyzeByAutocorrelation; // we call it to analyze sound by checking Autocorrelation - function AnalyzeAutocorrelationFreq(Freq: real): real; // use this to check one frequency by Autocorrelation - end; - - TSoundCardInput = record - Name: string; - end; - - TGenericSoundCard = class - // here can be the soundcard information - whole database from which user will select recording source - Description: string; // soundcard name/description - Input: array of TSoundCardInput; // soundcard input(-source)s - InputSelected: integer; // unused. What is this good for? - MicInput: integer; // unused. What is this good for? - //SampleRate: integer; // TODO: for sample-rate conversion (for devices that do not support 44.1kHz) - CaptureSoundLeft: TSound; // sound(-buffer) used for left channel capture data - CaptureSoundRight: TSound; // sound(-buffer) used for right channel capture data - end; - - TAudioInputProcessor = class - Sound: array of TSound; - SoundCard: array of TGenericSoundCard; - - constructor Create; - - // handle microphone input - procedure HandleMicrophoneData(Buffer: Pointer; Length: Cardinal; - InputDevice: TGenericSoundCard); - - function volume( aChannel : byte ): byte; - end; - - smallintarray = array [0..maxInt shr 1-1] of smallInt; - psmallintarray = ^smallintarray; - - function AudioInputProcessor(): TAudioInputProcessor; - -implementation - -uses UMain; - -var - singleton_AudioInputProcessor : TAudioInputProcessor = nil; - - -// FIXME: Race-Conditions between Callback-thread and main-thread -// on BufferArray (maybe BufferNew also). -// Use SDL-mutexes to solve this problem. - - -function AudioInputProcessor(): TAudioInputProcessor; -begin +unit URecord;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses Classes,
+ Math,
+ SysUtils,
+ UCommon,
+ UMusic,
+ UIni;
+
+type
+ TSound = class
+ private
+ BufferNew: TMemoryStream; // buffer for newest samples
+ public
+ BufferArray: array[0..4095] of smallint; // newest 4096 samples
+ BufferLong: array of TMemoryStream; // full buffer
+
+ Index: integer; // index in TAudioInputProcessor.Sound[] (TODO: Remove if not used)
+
+ AnalysisBufferSize: integer; // number of samples to analyze
+
+ // pitch detection
+ ToneValid: boolean; // true if Tone contains a valid value (otherwise it contains noise)
+ //Peak: integer; // position of peak on horizontal pivot (TODO: Remove if not used)
+ //ToneAccuracy: real; // tone accuracy (TODO: Remove if not used)
+ Tone: integer; // TODO: should be a non-unified full range tone (e.g. C2<>C3). Range: 0..NumHalftones-1
+ // Note: at the moment it is the same as ToneUnified
+ ToneUnified: integer; // tone unified to one octave (e.g. C2=C3=C4). Range: 0-11
+ //Scale: real; // FFT scale (TODO: Remove if not used)
+
+ // procedures
+ procedure ProcessNewBuffer;
+ procedure AnalyzeBuffer; // use to analyze sound from buffers to get new pitch
+ procedure AnalyzeByAutocorrelation; // we call it to analyze sound by checking Autocorrelation
+ function AnalyzeAutocorrelationFreq(Freq: real): real; // use this to check one frequency by Autocorrelation
+ end;
+
+ TAudioInputDeviceSource = record
+ Name: string;
+ end;
+
+ // soundcard input-devices information
+ TAudioInputDevice = class
+ public
+ CfgIndex: integer; // index of this device in Ini.InputDeviceConfig
+ Description: string; // soundcard name/description
+ Source: array of TAudioInputDeviceSource; // soundcard input(-source)s
+ SourceSelected: integer; // unused. What is this good for?
+ MicInput: integer; // unused. What is this good for?
+ SampleRate: integer; // capture sample-rate (e.g. 44.1kHz -> 44100)
+ CaptureChannel: array[0..1] of TSound; // sound(-buffers) used for left/right channel's capture data
+
+ procedure Start(); virtual; abstract;
+ procedure Stop(); virtual; abstract;
+
+ destructor Destroy; override;
+ end;
+
+ TAudioInputProcessor = class
+ Sound: array of TSound;
+ Device: array of TAudioInputDevice;
+
+ constructor Create;
+
+ // handle microphone input
+ procedure HandleMicrophoneData(Buffer: Pointer; Size: Cardinal;
+ InputDevice: TAudioInputDevice);
+
+ function Volume( aChannel : byte ): byte;
+ end;
+
+ TAudioInputBase = class( TInterfacedObject, IAudioInput )
+ private
+ Started: boolean;
+ protected
+ function UnifyDeviceName(const name: string; deviceIndex: integer): string;
+ function UnifyDeviceSourceName(const name: string; const deviceName: string): string;
+ public
+ function GetName: String; virtual; abstract;
+ function InitializeRecord: boolean; virtual; abstract;
+
+ procedure CaptureStart;
+ procedure CaptureStop;
+ end;
+
+
+ SmallIntArray = array [0..maxInt shr 1-1] of smallInt;
+ PSmallIntArray = ^SmallIntArray;
+
+ function AudioInputProcessor(): TAudioInputProcessor;
+
+implementation
+
+uses
+ ULog,
+ UMain;
+
+const
+ CaptureFreq = 44100;
+ BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz)
+ NumHalftones = 36; // C2-B4 (for Whitney and my high voice)
+
+var
+ singleton_AudioInputProcessor : TAudioInputProcessor = nil;
+
+
+// FIXME: Race-Conditions between Callback-thread and main-thread
+// on BufferArray (maybe BufferNew also).
+// Use SDL-mutexes to solve this problem.
+
+
+{ Global }
+
+function AudioInputProcessor(): TAudioInputProcessor;
+begin
if singleton_AudioInputProcessor = nil then
singleton_AudioInputProcessor := TAudioInputProcessor.create();
result := singleton_AudioInputProcessor;
-
end;
- -procedure TSound.ProcessNewBuffer; -var - S: integer; - L: integer; - A: integer; -begin - // process BufferArray - S := 0; - L := BufferNew.Size div 2; - if L > n then begin - S := L - n; - L := n; - end; - - // copy to array - for A := L+1 to n do - BufferArray[A-L] := BufferArray[A]; - - BufferNew.Seek(2*S, soBeginning); - BufferNew.ReadBuffer(BufferArray[1+n-L], 2*L); - - // process BufferLong - if Ini.SavePlayback = 1 then - begin - BufferNew.Seek(0, soBeginning); - BufferLong[0].CopyFrom(BufferNew, BufferNew.Size); - end; -end; - -procedure TSound.AnalyzeBuffer; -begin - AnalyzeByAutocorrelation; -end; - -procedure TSound.AnalyzeByAutocorrelation; -var - T: integer; // tone - F: real; // freq - Wages: array[0..35] of real; // wages - MaxT: integer; // max tone - MaxW: real; // max wage - V: real; // volume - MaxV: real; // max volume - S: integer; // Signal - Threshold: real; // threshold -begin - SzczytJest := false; - - // find maximum volume of first 1024 words of signal - MaxV := 0; - for S := 1 to 1024 do // 0.5.2: fix. was from 0 to 1023 - begin - V := Abs(BufferArray[S]) / $10000; - - if V > MaxV then - MaxV := V; - end; - - // prepare to analyze - MaxW := 0; - - // analyze all 12 halftones - for T := 0 to 35 do // to 11, then 23, now 35 (for Whitney and my high voice) - begin - F := 130.81 * Power(1.05946309436, T)/2; // let's analyze below 130.81 - Wages[T] := AnalyzeAutocorrelationFreq(F); - - if Wages[T] > MaxW then - begin // this frequency has better wage - MaxW := Wages[T]; - MaxT := T; - end; - end; // for T - - Threshold := 0.1; - case Ini.Threshold of - 0: Threshold := 0.05; - 1: Threshold := 0.1; - 2: Threshold := 0.15; - 3: Threshold := 0.2; - end; - - if MaxV >= Threshold then - begin // found acceptable volume // 0.1 - SzczytJest := true; - TonGamy := MaxT mod 12; - Ton := MaxT mod 12; - end; - -end; - -function TSound.AnalyzeAutocorrelationFreq(Freq: real): real; // result medium difference -var - Count: real; - Src: integer; - Dst: integer; - Move: integer; - Il: integer; // how many counts were done -begin - // we use Signal as source - Count := 0; - Il := 0; - Src := 1; - Move := Round(44100/Freq); - Dst := Src + Move; - - // ver 2 - compare in vertical - while (Dst < n) do - begin // process up to n (4KB) of Signal - Count := Count + Abs(BufferArray[Src] - BufferArray[Dst]) / $10000; - Inc(Src); - Inc(Dst); - Inc(Il); - end; - - Result := 1 - Count / Il; -end; - -{* - * Handle captured microphone input data. - * Params: - * Buffer - buffer of signed 16bit interleaved stereo PCM-samples. - * Interleaved means that a right-channel sample follows a left- - * channel sample and vice versa (0:left[0],1:right[0],2:left[1],...). - * Length - number of bytes in Buffer - * Input - Soundcard-Input used for capture - *} -procedure TAudioInputProcessor.HandleMicrophoneData(Buffer: Pointer; Length: Cardinal; InputDevice: TGenericSoundCard); -var - L: integer; - S: integer; - PB: pbytearray; - PSI: psmallintarray; - I: integer; - Skip: integer; - Boost: byte; -begin - // set boost - case Ini.MicBoost of - 0: Boost := 1; - 1: Boost := 2; - 2: Boost := 4; - 3: Boost := 8; - end; - - // boost buffer - L := Length div 2; // number of samples - PSI := Buffer; - for S := 0 to L-1 do - begin - I := PSI^[S] * Boost; - - // TODO : JB - This will clip the audio... cant we reduce the "Boot" if the data clips ?? - if I > 32767 then - I := 32767; // 0.5.0: limit - - if I < -32768 then - I := -32768; // 0.5.0: limit - - PSI^[S] := I; - end; - - // 2 players USB mic, left channel - if InputDevice.CaptureSoundLeft <> nil then - begin - L := Length div 4; // number of samples - PB := Buffer; - - InputDevice.CaptureSoundLeft.BufferNew.Clear; // 0.5.2: problem on exiting - for S := 0 to L-1 do - begin - InputDevice.CaptureSoundLeft.BufferNew.Write(PB[S*4], 2); - end; - InputDevice.CaptureSoundLeft.ProcessNewBuffer; - end; - - // 2 players USB mic, right channel - Skip := 2; - - if InputDevice.CaptureSoundRight <> nil then - begin - L := Length div 4; // number of samples - PB := Buffer; - InputDevice.CaptureSoundRight.BufferNew.Clear; - for S := 0 to L-1 do - begin - InputDevice.CaptureSoundRight.BufferNew.Write(PB[Skip + S*4], 2); - end; - InputDevice.CaptureSoundRight.ProcessNewBuffer; - end; -end; - -constructor TAudioInputProcessor.Create; -var - S: integer; -begin - SetLength(Sound, 6 {max players});//Ini.Players+1); - for S := 0 to High(Sound) do - begin //Ini.Players do begin - Sound[S] := TSound.Create; - Sound[S].Num := S; - Sound[S].BufferNew := TMemoryStream.Create; - SetLength(Sound[S].BufferLong, 1); - Sound[S].BufferLong[0] := TMemoryStream.Create; - Sound[S].n := 4*1024; - end; -end; - -function TAudioInputProcessor.volume( aChannel : byte ): byte; -var - lCount : Integer; - lMaxVol : double; -begin; - lMaxVol := AudioInputProcessor.Sound[aChannel].BufferArray[1]; - for lCount := 2 to AudioInputProcessor.Sound[aChannel].n div 1 do - begin - if AudioInputProcessor.Sound[aChannel].BufferArray[lCount] > lMaxVol then - lMaxVol := AudioInputProcessor.Sound[aChannel].BufferArray[lCount]; - end; - - result := trunc( ( 255 / 32767 ) * trunc( lMaxVol ) ); -end; - -end. - - - +
+
+{ TAudioInputDevice }
+
+destructor TAudioInputDevice.Destroy;
+var
+ i: integer;
+begin
+ Stop();
+ Source := nil;
+ for i := 0 to High(CaptureChannel) do
+ CaptureChannel[i] := nil;
+ inherited Destroy;
+end;
+
+
+{ TSound }
+
+procedure TSound.ProcessNewBuffer;
+var
+ SkipCount: integer;
+ NumSamples: integer;
+ SampleIndex: integer;
+begin
+ // process BufferArray
+ SkipCount := 0;
+ NumSamples := BufferNew.Size div 2;
+
+ // check if we have more new samples than we can store
+ if NumSamples > Length(BufferArray) then
+ begin
+ // discard the oldest of the new samples
+ SkipCount := NumSamples - Length(BufferArray);
+ NumSamples := Length(BufferArray);
+ end;
+
+ // move old samples to the beginning of the array (if necessary)
+ for SampleIndex := NumSamples to High(BufferArray) do
+ BufferArray[SampleIndex-NumSamples] := BufferArray[SampleIndex];
+
+ // skip samples if necessary
+ BufferNew.Seek(2*SkipCount, soBeginning);
+ // copy samples
+ BufferNew.ReadBuffer(BufferArray[Length(BufferArray)-NumSamples], 2*NumSamples);
+
+ // save capture-data to BufferLong if neccessary
+ if Ini.SavePlayback = 1 then
+ begin
+ BufferNew.Seek(0, soBeginning);
+ BufferLong[0].CopyFrom(BufferNew, BufferNew.Size);
+ end;
+end;
+
+procedure TSound.AnalyzeBuffer;
+begin
+ AnalyzeByAutocorrelation;
+end;
+
+procedure TSound.AnalyzeByAutocorrelation;
+var
+ ToneIndex: integer;
+ Freq: real;
+ Wages: array[0..NumHalftones-1] of real;
+ MaxTone: integer;
+ MaxWage: real;
+ Volume: real;
+ MaxVolume: real;
+ SampleIndex: integer;
+ Threshold: real;
+const
+ HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave)
+begin
+ ToneValid := false;
+
+ // find maximum volume of first 1024 samples
+ MaxVolume := 0;
+ for SampleIndex := 0 to 1023 do
+ begin
+ Volume := Abs(BufferArray[SampleIndex]) /
+ -Low(Smallint); // was $10000 (65536) before but must be 32768
+
+ if Volume > MaxVolume then
+ MaxVolume := Volume;
+ end;
+
+ // prepare to analyze
+ MaxWage := 0;
+
+ // analyze halftones
+ for ToneIndex := 0 to NumHalftones-1 do
+ begin
+ Freq := BaseToneFreq * Power(HalftoneBase, ToneIndex);
+ Wages[ToneIndex] := AnalyzeAutocorrelationFreq(Freq);
+
+ if Wages[ToneIndex] > MaxWage then
+ begin
+ // this frequency has better wage
+ MaxWage := Wages[ToneIndex];
+ MaxTone := ToneIndex;
+ end;
+ end;
+
+ Threshold := 0.2;
+ case Ini.Threshold of
+ 0: Threshold := 0.1;
+ 1: Threshold := 0.2;
+ 2: Threshold := 0.3;
+ 3: Threshold := 0.4;
+ end;
+
+ // check if signal has an acceptable volume (ignore background-noise)
+ if MaxVolume >= Threshold then
+ begin
+ ToneValid := true;
+ ToneUnified := MaxTone mod 12;
+ Tone := MaxTone mod 12;
+ end;
+
+end;
+
+function TSound.AnalyzeAutocorrelationFreq(Freq: real): real; // result medium difference
+var
+ Dist: real; // distance (0=equal .. 1=totally different) between correlated samples
+ AccumDist: real; // accumulated distances
+ SampleIndex: integer; // index of sample to analyze
+ CorrelatingSampleIndex: integer; // index of sample one period ahead
+ SamplesPerPeriod: integer; // samples in one period
+begin
+ SampleIndex := 0;
+ SamplesPerPeriod := Round(CaptureFreq/Freq);
+ CorrelatingSampleIndex := SampleIndex + SamplesPerPeriod;
+
+ AccumDist := 0;
+
+ // compare correlating samples
+ while (CorrelatingSampleIndex < AnalysisBufferSize) do
+ begin
+ // calc distance (correlation: 1-dist) to corresponding sample in next period
+ Dist := Abs(BufferArray[SampleIndex] - BufferArray[CorrelatingSampleIndex]) /
+ High(Word); // was $10000 (65536) before but must be 65535
+ AccumDist := AccumDist + Dist;
+ Inc(SampleIndex);
+ Inc(CorrelatingSampleIndex);
+ end;
+
+ // return "inverse" average distance (=correlation)
+ Result := 1 - AccumDist / AnalysisBufferSize;
+end;
+
+
+{ TAudioInputProcessor }
+
+{*
+ * Handle captured microphone input data.
+ * Params:
+ * Buffer - buffer of signed 16bit interleaved stereo PCM-samples.
+ * Interleaved means that a right-channel sample follows a left-
+ * channel sample and vice versa (0:left[0],1:right[0],2:left[1],...).
+ * Length - number of bytes in Buffer
+ * Input - Soundcard-Input used for capture
+ *}
+procedure TAudioInputProcessor.HandleMicrophoneData(Buffer: Pointer; Size: Cardinal; InputDevice: TAudioInputDevice);
+var
+ NumSamples: integer; // number of samples
+ SampleIndex: integer;
+ Value: integer;
+ ByteBuffer: PByteArray; // buffer handled as array of bytes
+ SampleBuffer: PSmallIntArray; // buffer handled as array of samples
+ Offset: integer;
+ Boost: byte;
+ ChannelCount: integer;
+ ChannelIndex: integer;
+ CaptureChannel: TSound;
+ SampleSize: integer;
+begin
+ // set boost
+ case Ini.MicBoost of
+ 0: Boost := 1;
+ 1: Boost := 2;
+ 2: Boost := 4;
+ 3: Boost := 8;
+ end;
+
+ // boost buffer
+ NumSamples := Size div 2;
+ SampleBuffer := Buffer;
+ for SampleIndex := 0 to NumSamples-1 do
+ begin
+ Value := SampleBuffer^[SampleIndex] * Boost;
+
+ // TODO : JB - This will clip the audio... cant we reduce the "Boost" if the data clips ??
+ if Value > High(Smallint) then
+ Value := High(Smallint);
+
+ if Value < Low(Smallint) then
+ Value := Low(Smallint);
+
+ SampleBuffer^[SampleIndex] := Value;
+ end;
+
+ // number of channels
+ ChannelCount := Length(InputDevice.CaptureChannel);
+ // size of one sample
+ SampleSize := ChannelCount * SizeOf(SmallInt);
+ // samples per channel
+ NumSamples := Size div SampleSize;
+
+ // interpret buffer as buffer of bytes
+ ByteBuffer := Buffer;
+
+ // process channels
+ for ChannelIndex := 0 to High(InputDevice.CaptureChannel) do
+ begin
+ CaptureChannel := InputDevice.CaptureChannel[ChannelIndex];
+ if (CaptureChannel <> nil) then
+ begin
+ Offset := ChannelIndex * SizeOf(SmallInt);
+
+ // TODO: remove BufferNew and write to BufferArray directly
+
+ CaptureChannel.BufferNew.Clear;
+ for SampleIndex := 0 to NumSamples-1 do
+ begin
+ CaptureChannel.BufferNew.Write(ByteBuffer^[Offset + SampleIndex*SampleSize],
+ SizeOf(SmallInt));
+ end;
+ CaptureChannel.ProcessNewBuffer();
+ end;
+ end;
+end;
+
+constructor TAudioInputProcessor.Create;
+var
+ i: integer;
+begin
+ SetLength(Sound, 6 {max players});//Ini.Players+1);
+ for i := 0 to High(Sound) do
+ begin
+ Sound[i] := TSound.Create;
+ Sound[i].Index := i;
+ Sound[i].BufferNew := TMemoryStream.Create;
+ SetLength(Sound[i].BufferLong, 1);
+ Sound[i].BufferLong[0] := TMemoryStream.Create;
+ Sound[i].AnalysisBufferSize := Min(4*1024, Length(Sound[i].BufferArray));
+ end;
+end;
+
+function TAudioInputProcessor.Volume( aChannel : byte ): byte;
+var
+ lSampleIndex: Integer;
+ lMaxVol : Word;
+begin;
+ with AudioInputProcessor.Sound[aChannel] do
+ begin
+ lMaxVol := BufferArray[0];
+ for lSampleIndex := 1 to High(BufferArray) do
+ begin
+ if Abs(BufferArray[lSampleIndex]) > lMaxVol then
+ lMaxVol := Abs(BufferArray[lSampleIndex]);
+ end;
+ end;
+
+ result := trunc( ( 255 / -Low(Smallint) ) * lMaxVol );
+end;
+
+
+{ TAudioInputBase }
+
+{*
+ * Start capturing on all used input-device.
+ *}
+procedure TAudioInputBase.CaptureStart;
+var
+ S: integer;
+ DeviceIndex: integer;
+ ChannelIndex: integer;
+ Device: TAudioInputDevice;
+ DeviceCfg: PInputDeviceConfig;
+ DeviceUsed: boolean;
+ Player: integer;
+begin
+ if (Started) then
+ CaptureStop();
+
+ Log.BenchmarkStart(1);
+
+ // reset buffers
+ for S := 0 to High(AudioInputProcessor.Sound) do
+ AudioInputProcessor.Sound[S].BufferLong[0].Clear;
+
+ // start capturing on each used device
+ for DeviceIndex := 0 to High(AudioInputProcessor.Device) do begin
+ Device := AudioInputProcessor.Device[DeviceIndex];
+ if not assigned(Device) then
+ continue;
+ DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
+
+ DeviceUsed := false;
+
+ // check if device is used
+ for ChannelIndex := 0 to High(DeviceCfg.ChannelToPlayerMap) do
+ begin
+ Player := DeviceCfg.ChannelToPlayerMap[ChannelIndex]-1;
+ if (Player < 0) or (Player >= PlayersPlay) then
+ begin
+ Device.CaptureChannel[ChannelIndex] := nil;
+ end
+ else
+ begin
+ Device.CaptureChannel[ChannelIndex] := AudioInputProcessor.Sound[Player];
+ DeviceUsed := true;
+ end;
+ end;
+
+ // start device if used
+ if (DeviceUsed) then begin
+ Log.BenchmarkStart(2);
+ Device.Start();
+ Log.BenchmarkEnd(2);
+ Log.LogBenchmark('Device.Start', 2) ; + end;
+ end;
+
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('CaptureStart', 1) ; +
+ Started := true;
+end;
+
+{*
+ * Stop input-capturing on all soundcards.
+ *}
+procedure TAudioInputBase.CaptureStop;
+var
+ DeviceIndex: integer;
+ Player: integer;
+ Device: TAudioInputDevice;
+ DeviceCfg: PInputDeviceConfig;
+begin
+ for DeviceIndex := 0 to High(AudioInputProcessor.Device) do begin
+ Device := AudioInputProcessor.Device[DeviceIndex];
+ if not assigned(Device) then
+ continue;
+ Device.Stop();
+ end;
+
+ Started := false;
+end;
+
+function TAudioInputBase.UnifyDeviceName(const name: string; deviceIndex: integer): string;
+var
+ count: integer; // count of devices with this name
+
+ function IsDuplicate(const name: string): boolean;
+ var
+ i: integer;
+ begin
+ Result := False;
+ // search devices with same description
+ For i := 0 to deviceIndex-1 do
+ begin
+ if (AudioInputProcessor.Device[i].Description = name) then
+ begin
+ Result := True;
+ Break;
+ end;
+ end;
+ end;
+begin
+ count := 1;
+ result := name;
+
+ // if there is another device with the same ID, search for an available name
+ while (IsDuplicate(result)) do
+ begin
+ Inc(count);
+ // set description
+ result := name + ' ('+IntToStr(count)+')';
+ end;
+end;
+
+{*
+ * Unifies an input-device's source name.
+ * Note: the description member of the device must already be set when
+ * calling this function.
+ *}
+function TAudioInputBase.UnifyDeviceSourceName(const name: string; const deviceName: string): string;
+var
+ Descr: string;
+begin
+ result := name;
+
+ {$IFDEF DARWIN}
+ // Under MacOSX the SingStar Mics have an empty
+ // InputName. So, we have to add a hard coded
+ // Workaround for this problem
+ if (name = '') and (Pos( 'USBMIC Serial#', deviceName) > 0) then
+ begin
+ result := 'Microphone';
+ end;
+ {$ENDIF}
+end;
+
+end.
+
+
+
diff --git a/Game/Code/Screens/UScreenCredits.pas b/Game/Code/Screens/UScreenCredits.pas index d5c9bebc..925d62cc 100644 --- a/Game/Code/Screens/UScreenCredits.pas +++ b/Game/Code/Screens/UScreenCredits.pas @@ -1,1402 +1,1402 @@ -unit UScreenCredits; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - - -uses - UMenu, - SDL, - SDL_Image, - UDisplay, - UTexture, - OpenGL12, - UMusic, - UFiles, - SysUtils, - UThemes, - ULCD, - ULight, - UGraphicClasses; - -type - TCreditsStages=(InitialDelay,Intro,MainPart,Outro); - - TScreenCredits = class(TMenu) - public - - Credits_X: Real; - Credits_Time: Cardinal; - Credits_Alpha: Cardinal; - CTime: Cardinal; - CTime_hold: Cardinal; - ESC_Alpha: Integer; - - credits_entry_tex: TTexture; - credits_entry_dx_tex: TTexture; - credits_bg_tex: TTexture; - credits_bg_ovl: TTexture; -// credits_bg_logo: TTexture; - credits_bg_scrollbox_left: TTexture; - credits_blindguard: TTexture; - credits_blindy: TTexture; - credits_canni: TTexture; - credits_commandio: TTexture; - credits_lazyjoker: TTexture; - credits_mog: TTexture; - credits_mota: TTexture; - credits_skillmaster: TTexture; - credits_whiteshark: TTexture; - intro_layer01: TTexture; - intro_layer02: TTexture; - intro_layer03: TTexture; - intro_layer04: TTexture; - intro_layer05: TTexture; - intro_layer06: TTexture; - intro_layer07: TTexture; - intro_layer08: TTexture; - intro_layer09: TTexture; - outro_bg: TTexture; - outro_esc: TTexture; - outro_exd: TTexture; - - deluxe_slidein: cardinal; - - CurrentScrollText: String; - NextScrollUpdate: Real; - EndofLastScrollingPart: Cardinal; - CurrentScrollStart, CurrentScrollEnd: Integer; - - CRDTS_Stage: TCreditsStages; - - myTex: glUint; - mysdlimage,myconvertedsdlimage: PSDL_Surface; - - Fadeout: boolean; - constructor Create; override; - function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; - function Draw: boolean; override; - procedure onShow; override; - procedure onHide; override; - procedure DrawCredits; - procedure Draw_FunkyText; - end; - -const - Funky_Text: AnsiString = - 'Grandma Deluxe has arrived! Thanks to Corvus5 for the massive work on UltraStar, Wome for the nice tune you´re hearing, '+ - 'all the people who put massive effort and work in new songs (don´t forget UltraStar w/o songs would be nothing), ppl from '+ - 'irc helping us - eBandit and Gabari, scene ppl who really helped instead of compiling and running away. Greetings to DennisTheMenace for betatesting, '+ - 'Demoscene.tv, pouet.net, KakiArts, Sourceforge,..'; - - - Timings: array[0..21] of Cardinal=( - 20, // 0 Delay vor Start - - 149, // 1 Ende erster Intro Zoom - 155, // 2 Start 2. Action im Intro - 170, // 3 Ende Separation im Intro - 271, // 4 Anfang Zoomout im Intro - 0, // 5 unused - 261, // 6 Start fade-to-white im Intro - - 271, // 7 Start Main Part - 280, // 8 Start On-Beat-Sternchen Main Part - - 396, // 9 Start BlindGuard - 666, // 10 Start blindy - 936, // 11 Start Canni - 1206, // 12 Start Commandio - 1476, // 13 Start LazyJoker - 1746, // 14 Start Mog - 2016, // 15 Start Mota - 2286, // 16 Start SkillMaster - 2556, // 17 Start WhiteShark - 2826, // 18 Ende Whiteshark - 3096, // 19 Start FadeOut Mainscreen - 3366, // 20 Ende Credits Tune - 60); // 21 start flare im intro - - - sdl32bpprgba: TSDL_Pixelformat=(palette: nil; - BitsPerPixel: 32; - BytesPerPixel: 4; - Rloss: 0; - Gloss: 0; - Bloss: 0; - Aloss: 0; - Rshift: 0; - Gshift: 8; - Bshift: 16; - Ashift: 24; - Rmask: $000000ff; - Gmask: $0000ff00; - Bmask: $00ff0000; - Amask: $ff000000; - colorkey: 0; - alpha: 255 ); - - -implementation - -uses {$IFDEF win32} - windows, - {$ELSE} - lclintf, - {$ENDIF} - ULog, - UGraphic, - UMain, - UIni, - USongs, - Textgl, - ULanguage, - UCommon, - Math, - dialogs; - - -function TScreenCredits.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; -begin - Result := true; - If (PressedDown) Then - begin // Key Down - case PressedKey of - - SDLK_ESCAPE, - SDLK_BACKSPACE : - begin - FadeTo(@ScreenMain); - AudioPlayback.PlayBack; - end; -{ SDLK_SPACE: - begin - setlength(CTime_hold,length(CTime_hold)+1); - CTime_hold[high(CTime_hold)]:=CTime; - end; -} - end;//esac - end; //fi -end; - -constructor TScreenCredits.Create; -begin - inherited Create; - - credits_bg_tex := Texture.LoadTexture(true, 'CRDTS_BG', 'PNG', 'Plain', 0); - credits_bg_ovl := Texture.LoadTexture(true, 'CRDTS_OVL', 'PNG', 'Transparent', 0); - - credits_blindguard := Texture.LoadTexture(true, 'CRDTS_blindguard', 'PNG', 'Font Black', 0); - credits_blindy := Texture.LoadTexture(true, 'CRDTS_blindy', 'PNG', 'Font Black', 0); - credits_canni := Texture.LoadTexture(true, 'CRDTS_canni', 'PNG', 'Font Black', 0); - credits_commandio := Texture.LoadTexture(true, 'CRDTS_commandio', 'PNG', 'Font Black', 0); - credits_lazyjoker := Texture.LoadTexture(true, 'CRDTS_lazyjoker', 'PNG', 'Font Black', 0); - credits_mog := Texture.LoadTexture(true, 'CRDTS_mog', 'PNG', 'Font Black', 0); - credits_mota := Texture.LoadTexture(true, 'CRDTS_mota', 'PNG', 'Font Black', 0); - credits_skillmaster := Texture.LoadTexture(true, 'CRDTS_skillmaster', 'PNG', 'Font Black', 0); - credits_whiteshark := Texture.LoadTexture(true, 'CRDTS_whiteshark', 'PNG', 'Font Black', 0); - - intro_layer01 := Texture.LoadTexture(true, 'INTRO_L01', 'PNG', 'Transparent', 0); - intro_layer02 := Texture.LoadTexture(true, 'INTRO_L02', 'PNG', 'Transparent', 0); - intro_layer03 := Texture.LoadTexture(true, 'INTRO_L03', 'PNG', 'Transparent', 0); - intro_layer04 := Texture.LoadTexture(true, 'INTRO_L04', 'PNG', 'Transparent', 0); - intro_layer05 := Texture.LoadTexture(true, 'INTRO_L05', 'PNG', 'Transparent', 0); - intro_layer06 := Texture.LoadTexture(true, 'INTRO_L06', 'PNG', 'Transparent', 0); - intro_layer07 := Texture.LoadTexture(true, 'INTRO_L07', 'PNG', 'Transparent', 0); - intro_layer08 := Texture.LoadTexture(true, 'INTRO_L08', 'PNG', 'Transparent', 0); - intro_layer09 := Texture.LoadTexture(true, 'INTRO_L09', 'PNG', 'Transparent', 0); - - outro_bg := Texture.LoadTexture(true, 'OUTRO_BG', 'PNG', 'Plain', 0); - outro_esc := Texture.LoadTexture(true, 'OUTRO_ESC', 'PNG', 'Transparent', 0); - outro_exd := Texture.LoadTexture(true, 'OUTRO_EXD', 'PNG', 'Transparent', 0); - - CRDTS_Stage:=InitialDelay; -end; - -function TScreenCredits.Draw: boolean; -begin - DrawCredits; - Draw:=true; -end; - -function pixfmt_eq(fmt1,fmt2: TSDL_Pixelformat): boolean; -begin - if (fmt1.BitsPerPixel = fmt2.BitsPerPixel) and - (fmt1.BytesPerPixel = fmt2.BytesPerPixel) and - (fmt1.Rloss = fmt2.Rloss) and - (fmt1.Gloss = fmt2.Gloss) and - (fmt1.Bloss = fmt2.Bloss) and - (fmt1.Rmask = fmt2.Rmask) and - (fmt1.Gmask = fmt2.Gmask) and - (fmt1.Bmask = fmt2.Bmask) and - (fmt1.Rshift = fmt2.Rshift) and - (fmt1.Gshift = fmt2.Gshift) and - (fmt1.Bshift = fmt2.Bshift) - then - pixfmt_eq:=True - else - pixfmt_eq:=False; -end; - -function inttohexstr(i: cardinal):pchar; -var helper, i2, c:cardinal; - tmpstr: string; -begin - helper:=0; - i2:=i; - tmpstr:=''; - for c:=1 to 8 do - begin - helper:=(helper shl 4) or (i2 and $f); - i2:=i2 shr 4; - end; - for c:=1 to 8 do - begin - i2:=helper and $f; - helper := helper shr 4; - case i2 of - 0: tmpstr:=tmpstr+'0'; - 1: tmpstr:=tmpstr+'1'; - 2: tmpstr:=tmpstr+'2'; - 3: tmpstr:=tmpstr+'3'; - 4: tmpstr:=tmpstr+'4'; - 5: tmpstr:=tmpstr+'5'; - 6: tmpstr:=tmpstr+'6'; - 7: tmpstr:=tmpstr+'7'; - 8: tmpstr:=tmpstr+'8'; - 9: tmpstr:=tmpstr+'9'; - 10: tmpstr:=tmpstr+'a'; - 11: tmpstr:=tmpstr+'b'; - 12: tmpstr:=tmpstr+'c'; - 13: tmpstr:=tmpstr+'d'; - 14: tmpstr:=tmpstr+'e'; - 15: tmpstr:=tmpstr+'f'; - end; - end; - inttohexstr:=pchar(tmpstr); -end; - -procedure TScreenCredits.onShow; -begin - CRDTS_Stage:=InitialDelay; - Credits_X := 580; - deluxe_slidein := 0; - Credits_Alpha := 0; - //Music.SetLoop(true); Loop looped ned, so ne scheisse - AudioPlayback.Open(soundpath + 'wome-credits-tune.mp3'); //danke kleinster liebster weeeetüüüüü!! -// Music.Play; - CTime:=0; -// setlength(CTime_hold,0); - - mysdlimage:=IMG_Load('test.png'); - if assigned(mysdlimage) then - begin - {$IFNDEF FPC} - showmessage('opened image via SDL_Image'+#13#10+ - 'Width: '+inttostr(mysdlimage^.w)+#13#10+ - 'Height: '+inttostr(mysdlimage^.h)+#13#10+ - 'BitsPP: '+inttostr(mysdlimage^.format.BitsPerPixel)+#13#10+ - 'BytesPP: '+inttostr(mysdlimage^.format.BytesPerPixel)+#13#10+ - 'Rloss: '+inttostr(mysdlimage^.format.Rloss)+#13#10+ - 'Gloss: '+inttostr(mysdlimage^.format.Gloss)+#13#10+ - 'Bloss: '+inttostr(mysdlimage^.format.Bloss)+#13#10+ - 'Aloss: '+inttostr(mysdlimage^.format.Aloss)+#13#10+ - 'Rshift: '+inttostr(mysdlimage^.format.Rshift)+#13#10+ - 'Gshift: '+inttostr(mysdlimage^.format.Gshift)+#13#10+ - 'Bshift: '+inttostr(mysdlimage^.format.Bshift)+#13#10+ - 'Ashift: '+inttostr(mysdlimage^.format.Ashift)+#13#10+ - 'Rmask: '+inttohexstr(mysdlimage^.format.Rmask)+#13#10+ - 'Gmask: '+inttohexstr(mysdlimage^.format.Gmask)+#13#10+ - 'Bmask: '+inttohexstr(mysdlimage^.format.Bmask)+#13#10+ - 'Amask: '+inttohexstr(mysdlimage^.format.Amask)+#13#10+ - 'ColKey: '+inttostr(mysdlimage^.format.Colorkey)+#13#10+ - 'Alpha: '+inttostr(mysdlimage^.format.Alpha)); - - if pixfmt_eq(mysdlimage^.format^,sdl32bpprgba) then - showmessage('equal pixelformats') - else - showmessage('different pixelformats'); - {$ENDIF} - - myconvertedsdlimage:=SDL_ConvertSurface(mysdlimage,@sdl32bpprgba,SDL_SWSURFACE); - glGenTextures(1,@myTex); - glBindTexture(GL_TEXTURE_2D, myTex); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexImage2D( GL_TEXTURE_2D, 0, 4, myconvertedsdlimage^.w, myconvertedsdlimage^.h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, myconvertedsdlimage^.pixels ); - SDL_FreeSurface(mysdlimage); - SDL_FreeSurface(myconvertedsdlimage); - end - else - {$IFDEF FPC} - writeln( 'could not open file - test.png'); - {$ELSE} - showmessage('could not open file - test.png'); - {$ENDIF} - -end; - -procedure TScreenCredits.onHide; -begin - AudioPlayback.Stop; -end; - -Procedure TScreenCredits.Draw_FunkyText; -var - S: Integer; - X,Y,A: Real; - visibleText: PChar; -begin - SetFontSize(10); - //Init ScrollingText - if (CTime = Timings[7]) then - begin - //Set Position of Text - Credits_X := 600; - CurrentScrollStart:=1; - CurrentScrollEnd:=1; - end; - - if (CTime > Timings[7]) and (CurrentScrollStart < length(Funky_Text)) then - begin - X:=0; - visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd)); - for S := 0 to length(visibleText)-1 do begin - Y:=abs(sin((Credits_X+X)*0.93{*(((Credits_X+X))/1200)}/100*pi)); - SetFontPos(Credits_X+X,538-Y*(Credits_X+X)*(Credits_X+X)*(Credits_X+X)/1000000); - A:=0; - if (Credits_X+X < 15) then A:=0; - if (Credits_X+X >=15) then A:=Credits_X+X-15; - if Credits_X+X > 32 then A:=17; - glColor4f( 230/255-40/255+Y*(Credits_X+X)/900, 200/255-30/255+Y*(Credits_X+X)/1000, 155/255-20/255+Y*(Credits_X+X)/1100, A/17); - glPrintLetter(visibleText[S]); - X := X + Fonts[ActFont].Width[Ord(visibleText[S])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW; - end; - if (Credits_X<0) and (CurrentScrollStart < length(Funky_Text)) then begin - Credits_X:=Credits_X + Fonts[ActFont].Width[Ord(Funky_Text[CurrentScrollStart])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW; - inc(CurrentScrollStart); - end; - visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd)); - if (Credits_X+glTextWidth(visibleText) < 600) and (CurrentScrollEnd < length(Funky_Text)) then begin - inc(CurrentScrollEnd); - end; - end; -{ // timing hack - X:=5; - SetFontStyle (2); - SetFontItalic(False); - SetFontSize(9); - glColor4f(1, 1, 1, 1); - for S:=0 to high(CTime_hold) do begin - visibleText:=pchar(inttostr(CTime_hold[S])); - SetFontPos (500, X); - glPrint (Addr(visibleText[0])); - X:=X+20; - end;} -end; - -procedure Start3D; -begin - glMatrixMode(GL_PROJECTION); - glPushMatrix; - glLoadIdentity; - glFrustum(-0.3*4/3,0.3*4/3,-0.3,0.3,1,1000); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity; -end; -procedure End3D; -begin - glMatrixMode(GL_PROJECTION); - glPopMatrix; - glMatrixMode(GL_MODELVIEW); -end; - -procedure TScreenCredits.DrawCredits; -var - T,I: Cardinal; - X: Real; - Ver: PChar; - RuntimeStr: AnsiString; - Data: TFFTData; - j,k,l:cardinal; - f,g,h: Real; - STime:cardinal; - Delay:cardinal; - - myPixel: longword; - myColor: Cardinal; - myScale: Real; - myAngle: Real; - - -const myLogoCoords: Array[0..27,0..1] of Cardinal = ((39,32),(84,32),(100,16),(125,24), - (154,31),(156,58),(168,32),(203,36), - (258,34),(251,50),(274,93),(294,84), - (232,54),(278,62),(319,34),(336,92), - (347,23),(374,32),(377,58),(361,83), - (385,91),(405,91),(429,35),(423,51), - (450,32),(485,34),(444,91),(486,93)); - -begin - //dis does teh muiwk y0r - Data := AudioPlayback.GetFFTData; - - Log.LogStatus('',' JB-1'); - - T := GetTickCount div 33; - if T <> Credits_Time then - begin - Credits_Time := T; - inc(CTime); - inc(CTime_hold); - Credits_X := Credits_X-2; - - Log.LogStatus('',' JB-2'); - if (CRDTS_Stage=InitialDelay) and (CTime=Timings[0]) then - begin -// CTime:=Timings[20]; -// CRDTS_Stage:=Outro; - - CRDTS_Stage:=Intro; - CTime:=0; - AudioPlayback.Play; - - end; - if (CRDTS_Stage=Intro) and (CTime=Timings[7]) then - begin - CRDTS_Stage:=MainPart; - end; - if (CRDTS_Stage=MainPart) and (CTime=Timings[20]) then - begin - CRDTS_Stage:=Outro; - end; - end; - - Log.LogStatus('',' JB-3'); - - //draw background - if CRDTS_Stage=InitialDelay then - begin - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - end - else - if CRDTS_Stage=Intro then - begin - Start3D; - glPushMatrix; - - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - if CTime < Timings[1] then begin - myScale:= 0.5+0.5*(Timings[1]-CTime)/(Timings[1]); // slowly move layers together - myAngle:=cos((CTime)*pi/((Timings[1])*2)); // and make logo face towards camera - end else begin // this is the part when the logo stands still - myScale:=0.5; - myAngle:=0; - end; - if CTime > Timings[2] then begin - myScale:= 0.5+0.5*(CTime-Timings[2])/(Timings[3]-Timings[2]); // get some space between layers - myAngle:=0; - end; -// if CTime > Timings[3] then myScale:=1; // keep the space between layers - glTranslatef(0,0,-5+0.5*myScale); - if CTime > Timings[3] then myScale:=1; // keep the space between layers - if CTime > Timings[3] then begin // make logo rotate left and grow -// myScale:=(CTime-Timings[4])/(Timings[7]-Timings[4]); - glRotatef(20*sqr(CTime-Timings[3])/sqr((Timings[7]-Timings[3])/2),0,0,1); - glScalef(1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1); - end; - if CTime < Timings[2] then - glRotatef(30*myAngle,0.5*myScale+myScale,1+myScale,0); -// glScalef(0.5,0.5,0.5); - glScalef(4/3,-1,1); - glColor4f(1, 1, 1, 1); - - glBindTexture(GL_TEXTURE_2D, intro_layer01.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, -0.4 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, -0.4 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, -0.4 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, -0.4 * myScale); - glEnd; - glBindTexture(GL_TEXTURE_2D, intro_layer02.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, -0.3 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, -0.3 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, -0.3 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, -0.3 * myScale); - glEnd; - glBindTexture(GL_TEXTURE_2D, intro_layer03.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, -0.2 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, -0.2 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, -0.2 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, -0.2 * myScale); - glEnd; - glBindTexture(GL_TEXTURE_2D, intro_layer04.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, -0.1 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, -0.1 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, -0.1 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, -0.1 * myScale); - glEnd; - glBindTexture(GL_TEXTURE_2D, intro_layer05.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, 0 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, 0 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, 0 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, 0 * myScale); - glEnd; - glBindTexture(GL_TEXTURE_2D, intro_layer06.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, 0.1 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, 0.1 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, 0.1 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, 0.1 * myScale); - glEnd; - glBindTexture(GL_TEXTURE_2D, intro_layer07.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, 0.2 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, 0.2 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, 0.2 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, 0.2 * myScale); - glEnd; - glBindTexture(GL_TEXTURE_2D, intro_layer08.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, 0.3 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, 0.3 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, 0.3 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, 0.3 * myScale); - glEnd; - glBindTexture(GL_TEXTURE_2D, intro_layer09.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex3f(-1, -1, 0.22 * myScale); - glTexCoord2f(0,1);glVertex3f(-1, 1, 0.22 * myScale); - glTexCoord2f(1,1); glVertex3f(1, 1, 0.22 * myScale); - glTexCoord2f(1,0);glVertex3f(1, -1, 0.22 * myScale); - glEnd; - gldisable(gl_texture_2d); - glDisable(GL_BLEND); - - glPopMatrix; - End3D; - - // do some sparkling effects - if (CTime < Timings[1]) and (CTime > Timings[21]) then - begin - for k:=1 to 3 do begin - l:=410+floor((CTime-Timings[21])/(Timings[1]-Timings[21])*(536-410))+RandomRange(-5,5); - j:=floor((Timings[1]-CTime)/22)+RandomRange(285,301); - GoldenRec.Spawn(l, j, 1, 16, 0, -1, Flare, 0); - end; - end; - - // fade to white at end - if Ctime > Timings[6] then - begin - glColor4f(1,1,1,sqr(Ctime-Timings[6])*(Ctime-Timings[6])/sqr(Timings[7]-Timings[6])); - glEnable(GL_BLEND); - glBegin(GL_QUADS); - glVertex2f(0,0); - glVertex2f(0,600); - glVertex2f(800,600); - glVertex2f(800,0); - glEnd; - glDisable(GL_BLEND); - end; - - end; - if (CRDTS_Stage=MainPart) then - // main credits screen background, scroller, logo and girl - begin - - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - glColor4f(1, 1, 1, 1); - glBindTexture(GL_TEXTURE_2D, credits_bg_tex.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(0, 0); - glTexCoord2f(0,600/1024);glVertex2f(0, 600); - glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600); - glTexCoord2f(800/1024,0);glVertex2f(800, 0); - glEnd; - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - // draw scroller - Draw_FunkyText; - -//######################################################################### -// draw credits names - - -Log.LogStatus('',' JB-4'); - -// BlindGuard (von links oben reindrehen, nach rechts unten rausdrehen) - STime:=Timings[9]-10; - Delay:=Timings[10]-Timings[9]; - if CTime > STime then - begin - k:=0; - ESC_Alpha:=20; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)<20) then ESC_Alpha:=20; - if CTime <=STime+10 then j:=CTime-STime else j:=10; - if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j/10); - - if (CTime >= STime+10) and (CTime<=STime+12) then begin - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - end; - - glPushMatrix; - gltranslatef(0,329,0); - if CTime <= STime+10 then begin glrotatef((CTime-STime)*9+270,0,0,1);end; - gltranslatef(223,0,0); - if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin - gltranslatef(223,0,0); - glrotatef((integer(CTime)-(integer(STime+Delay)-10))*-9,0,0,1); - gltranslatef(-223,0,0); - end; - glBindTexture(GL_TEXTURE_2D, credits_blindguard.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163, -129); - glTexCoord2f(0,1);glVertex2f(-163, 129); - glTexCoord2f(1,1); glVertex2f(163, 129); - glTexCoord2f(1,0);glVertex2f(163, -129); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - -// Blindy (zoom von 0 auf volle grösse und drehung, zoom auf doppelte grösse und nach rechts oben schieben) - STime:=Timings[10]-10; - Delay:=Timings[11]-Timings[10]+5; - if CTime > STime then - begin - k:=0; - ESC_Alpha:=20; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)<20) then ESC_Alpha:=20; - if CTime <=STime+10 then j:=CTime-STime else j:=10; - if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j/10); - - if (CTime >= STime+20) and (CTime<=STime+22) then begin - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - end; - - glPushMatrix; - gltranslatef(223,329,0); - if CTime <= STime+20 then begin - j:=CTime-Stime; - glscalef(j*j/400,j*j/400,j*j/400); - glrotatef(j*18.0,0,0,1); - end; - if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin - j:=CTime-(STime+Delay-10); - f:=j*10.0; - gltranslatef(f*3,-f,0); - glscalef(1+j/10,1+j/10,1+j/10); - glrotatef(j*9.0,0,0,1); - end; - glBindTexture(GL_TEXTURE_2D, credits_blindy.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163, -129); - glTexCoord2f(0,1);glVertex2f(-163, 129); - glTexCoord2f(1,1); glVertex2f(163, 129); - glTexCoord2f(1,0);glVertex2f(163, -129); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - -// Canni (von links reinschieben, nach rechts oben rausschieben) - STime:=Timings[11]-10; - Delay:=Timings[12]-Timings[11]+5; - if CTime > STime then - begin - k:=0; - ESC_Alpha:=20; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)<20) then ESC_Alpha:=20; - if CTime <=STime+10 then j:=CTime-STime else j:=10; - if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j/10); - - if (CTime >= STime+10) and (CTime<=STime+12) then begin - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - end; - - glPushMatrix; - gltranslatef(223,329,0); - if CTime <= STime+10 then begin - gltranslatef(((CTime-STime)*21.0)-210,0,0); - end; - if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin - j:=(CTime-(STime+Delay-10))*21; - gltranslatef(j,-j/2,0); - end; - glBindTexture(GL_TEXTURE_2D, credits_canni.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163, -129); - glTexCoord2f(0,1);glVertex2f(-163, 129); - glTexCoord2f(1,1); glVertex2f(163, 129); - glTexCoord2f(1,0);glVertex2f(163, -129); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - -// Commandio (von unten reinklappen, nach rechts oben rausklappen) - STime:=Timings[12]-10; - Delay:=Timings[13]-Timings[12]; - if CTime > STime then - begin - k:=0; - ESC_Alpha:=20; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)<20) then ESC_Alpha:=20; - if CTime <=STime+10 then j:=CTime-STime else j:=10; - if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j/10); - - if (CTime >= STime+10) and (CTime<=STime+12) then begin - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - end; - - glPushMatrix; - gltranslatef(223,329,0); - if CTime <= STime+10 then - f:=258.0-25.8*(CTime-STime) - else - f:=0; - g:=0; - if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin - j:=CTime-(STime+Delay-10); - g:=32.6*j; - end; - glBindTexture(GL_TEXTURE_2D, credits_commandio.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163+g-f*1.5, -129+f*1.5-g/2); - glTexCoord2f(0,1);glVertex2f(-163+g*1.5, 129-(g*1.5*258/326)); - glTexCoord2f(1,1); glVertex2f(163+g, 129+g/4); - glTexCoord2f(1,0);glVertex2f(163+f*1.5+g/4, -129+f*1.5-g/4); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - -// lazy joker (just scrolls from left to right, no twinkling stars, no on-beat flashing) - STime:=Timings[13]-35; - Delay:=Timings[14]-Timings[13]+5; - if CTime > STime then - begin - k:=0; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)>10) and ((CTime-STime)<20) then ESC_Alpha:=20; - ESC_Alpha:=10; - f:=CTime-STime; - if CTime <=STime+40 then j:=CTime-STime else j:=40; - if (CTime >=STime+Delay-40) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j*j/1600); - - glPushMatrix; - gltranslatef(180+(f-70),329,0); - glBindTexture(GL_TEXTURE_2D, credits_lazyjoker.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163, -129); - glTexCoord2f(0,1);glVertex2f(-163, 129); - glTexCoord2f(1,1); glVertex2f(163, 129); - glTexCoord2f(1,0);glVertex2f(163, -129); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - -// Mog (von links reinklappen, nach rechts unten rausklappen) - STime:=Timings[14]-10; - Delay:=Timings[15]-Timings[14]+5; - if CTime > STime then - begin - k:=0; - ESC_Alpha:=20; - - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)<20) then ESC_Alpha:=20; - if CTime <=STime+10 then j:=CTime-STime else j:=10; - if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j/10); - - if (CTime >= STime+10) and (CTime<=STime+12) then begin - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - end; - - glPushMatrix; - gltranslatef(223,329,0); - if CTime <= STime+10 then - f:=326.0-32.6*(CTime-STime) - else - f:=0; - - g:=0; - if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin - j:=CTime-(STime+Delay-10); - g:=32.6*j; - end; - glBindTexture(GL_TEXTURE_2D, credits_mog.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163+g*1.5, -129+g*1.5); - glTexCoord2f(0,1);glVertex2f(-163+g*1.2, 129+g); - glTexCoord2f(1,1); glVertex2f(163-f+g/2, 129+f*1.5+g/4); - glTexCoord2f(1,0);glVertex2f(163-f+g*1.5, -129-f*1.5); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - -// Mota (von rechts oben reindrehen, nach links unten rausschieben und verkleinern und dabei drehen) - STime:=Timings[15]-10; - Delay:=Timings[16]-Timings[15]+5; - if CTime > STime then - begin - k:=0; - ESC_Alpha:=20; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)<20) then ESC_Alpha:=20; - if CTime <=STime+10 then j:=CTime-STime else j:=10; - if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j/10); - - if (CTime >= STime+10) and (CTime<=STime+12) then begin - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - end; - - glPushMatrix; - gltranslatef(223,329,0); - if CTime <= STime+10 then begin - gltranslatef(223,0,0); - glrotatef((10-(CTime-STime))*9,0,0,1); - gltranslatef(-223,0,0); - end; - if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin - j:=CTime-(STime+Delay-10); - f:=j*10.0; - gltranslatef(-f*2,-f,0); - glscalef(1-j/10,1-j/10,1-j/10); - glrotatef(-j*9.0,0,0,1); - end; - glBindTexture(GL_TEXTURE_2D, credits_mota.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163, -129); - glTexCoord2f(0,1);glVertex2f(-163, 129); - glTexCoord2f(1,1); glVertex2f(163, 129); - glTexCoord2f(1,0);glVertex2f(163, -129); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - -// Skillmaster (von rechts unten reinschieben, nach rechts oben rausdrehen) - STime:=Timings[16]-10; - Delay:=Timings[17]-Timings[16]+5; - if CTime > STime then - begin - k:=0; - ESC_Alpha:=20; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)<20) then ESC_Alpha:=20; - if CTime <=STime+10 then j:=CTime-STime else j:=10; - if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j/10); - - if (CTime >= STime+10) and (CTime<=STime+12) then begin - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - end; - - glPushMatrix; - gltranslatef(223,329,0); - if CTime <= STime+10 then begin - j:=STime+10-CTime; - f:=j*10.0; - gltranslatef(+f*2,+f/2,0); - end; - if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin - j:=CTime-(STime+Delay-10); - gltranslatef(0,-223,0); - glrotatef(integer(j)*-9,0,0,1); - gltranslatef(0,223,0); - glrotatef(j*9,0,0,1); - end; - glBindTexture(GL_TEXTURE_2D, credits_skillmaster.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163, -129); - glTexCoord2f(0,1);glVertex2f(-163, 129); - glTexCoord2f(1,1); glVertex2f(163, 129); - glTexCoord2f(1,0);glVertex2f(163, -129); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - -// WhiteShark (von links unten reinklappen, nach rechts oben rausklappen) - STime:=Timings[17]-10; - Delay:=Timings[18]-Timings[17]; - if CTime > STime then - begin - k:=0; - ESC_Alpha:=20; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - - if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha); - if ESC_Alpha >20 then ESC_Alpha:=20; - if ((CTime-STime)<20) then ESC_Alpha:=20; - if CTime <=STime+10 then j:=CTime-STime else j:=10; - if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0; - glColor4f(1, 1, 1, ESC_Alpha/20*j/10); - - if (CTime >= STime+10) and (CTime<=STime+12) then begin - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1); - GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5); - end; - - glPushMatrix; - gltranslatef(223,329,0); - if CTime <= STime+10 then - f:=326.0-32.6*(CTime-STime) - else - f:=0; - - if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin - j:=CTime-(STime+Delay-10); - g:=32.6*j; - end else - g:=0; - glBindTexture(GL_TEXTURE_2D, credits_whiteshark.TexNum); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(-163-f+g, -129+f/4-g/2); - glTexCoord2f(0,1);glVertex2f(-163-f/4+g, 129+g/2+f/4); - glTexCoord2f(1,1); glVertex2f(163-f*1.2+g/4, 129+f/2-g/4); - glTexCoord2f(1,0);glVertex2f(163-f*1.5+g/4, -129+f*1.5+g/4); - glEnd; - gldisable(gl_texture_2d); - gldisable(GL_BLEND); - glPopMatrix; - end; - - - Log.LogStatus('',' JB-103'); - -// #################################################################### -// do some twinkle stuff (kinda on beat) - if (CTime > Timings[8] ) and - (CTime < Timings[19] ) then - begin - k := 0; - - try - for j:=0 to 40 do - begin - if ( j < length( Data ) ) AND - ( k < length( Data ) ) then - begin - if Data[j] >= Data[k] then - k:=j; - end; - end; - except - end; - - if Data[k]>0.2 then - begin - l := RandomRange(6,16); - j := RandomRange(0,27); - - GoldenRec.Spawn(myLogoCoords[j,0], myLogoCoords[j,1], 16-l, l, 0, -1, PerfectNote, 0); - end; - end; - -//################################################# -// draw the rest of the main screen (girl and logo - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glColor4f(1, 1, 1, 1); - glBindTexture(GL_TEXTURE_2D, credits_bg_ovl.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(800-393, 0); - glTexCoord2f(0,600/1024);glVertex2f(800-393, 600); - glTexCoord2f(393/512,600/1024); glVertex2f(800, 600); - glTexCoord2f(393/512,0);glVertex2f(800, 0); - glEnd; -{ glBindTexture(GL_TEXTURE_2D, credits_bg_logo.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(0, 0); - glTexCoord2f(0,112/128);glVertex2f(0, 112); - glTexCoord2f(497/512,112/128); glVertex2f(497, 112); - glTexCoord2f(497/512,0);glVertex2f(497, 0); - glEnd; -} - gldisable(gl_texture_2d); - glDisable(GL_BLEND); - - // fade out at end of main part - if Ctime > Timings[19] then - begin - glColor4f(0,0,0,(Ctime-Timings[19])/(Timings[20]-Timings[19])); - glEnable(GL_BLEND); - glBegin(GL_QUADS); - glVertex2f(0,0); - glVertex2f(0,600); - glVertex2f(800,600); - glVertex2f(800,0); - glEnd; - glDisable(GL_BLEND); - end; - end - else - if (CRDTS_Stage=Outro) then - begin - if CTime=Timings[20] then begin - CTime_hold:=0; - AudioPlayback.Stop; - AudioPlayback.Open(soundpath + 'credits-outro-tune.mp3'); - AudioPlayback.Play; - AudioPlayback.SetVolume(20); - AudioPlayback.SetLoop(True); - end; - if CTime_hold > 231 then begin - AudioPlayback.Play; - Ctime_hold:=0; - end; - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - - // do something useful - // outro background - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - glColor4f(1, 1, 1, 1); - glBindTexture(GL_TEXTURE_2D, outro_bg.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(0, 0); - glTexCoord2f(0,600/1024);glVertex2f(0, 600); - glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600); - glTexCoord2f(800/1024,0);glVertex2f(800, 0); - glEnd; - - //outro overlays - glColor4f(1, 1, 1, (1+sin(CTime/15))/3+1/3); - glBindTexture(GL_TEXTURE_2D, outro_esc.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(0, 0); - glTexCoord2f(0,223/256);glVertex2f(0, 223); - glTexCoord2f(487/512,223/256); glVertex2f(487, 223); - glTexCoord2f(487/512,0);glVertex2f(487, 0); - glEnd; - - ESC_Alpha:=20; - if (RandomRange(0,20) > 18) and (ESC_Alpha=20) then - ESC_Alpha:=0 - else inc(ESC_Alpha); - if ESC_Alpha > 20 then ESC_Alpha:=20; - glColor4f(1, 1, 1, ESC_Alpha/20); - glBindTexture(GL_TEXTURE_2D, outro_exd.TexNum); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(800-310, 600-247); - glTexCoord2f(0,247/256);glVertex2f(800-310, 600); - glTexCoord2f(310/512,247/256); glVertex2f(800, 600); - glTexCoord2f(310/512,0);glVertex2f(800, 600-247); - glEnd; - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - // outro scrollers? - // ... - end; - -{ // draw credits runtime counter - SetFontStyle (2); - SetFontItalic(False); - SetFontSize(9); - SetFontPos (5, 5); - glColor4f(1, 1, 1, 1); -// RuntimeStr:='CTime: '+inttostr(floor(CTime/30.320663991914489602156136106092))+'.'+inttostr(floor(CTime/3.0320663991914489602156136106092)-floor(CTime/30.320663991914489602156136106092)*10); - RuntimeStr:='CTime: '+inttostr(CTime); - glPrint (Addr(RuntimeStr[1])); -} - - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glColor4f(1, 1, 1, 1); - glBindTexture(GL_TEXTURE_2D, myTex); - glbegin(gl_quads); - glTexCoord2f(0,0);glVertex2f(100, 100); - glTexCoord2f(0,1);glVertex2f(100, 200); - glTexCoord2f(1,1); glVertex2f(200, 200); - glTexCoord2f(1,0);glVertex2f(200, 100); - glEnd; - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - - // make the stars shine - GoldenRec.Draw; -end; - -end. +unit UScreenCredits;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ UMenu,
+ SDL,
+ SDL_Image,
+ UDisplay,
+ UTexture,
+ OpenGL12,
+ UMusic,
+ UFiles,
+ SysUtils,
+ UThemes,
+ ULCD,
+ ULight,
+ UGraphicClasses;
+
+type
+ TCreditsStages=(InitialDelay,Intro,MainPart,Outro);
+
+ TScreenCredits = class(TMenu)
+ public
+
+ Credits_X: Real;
+ Credits_Time: Cardinal;
+ Credits_Alpha: Cardinal;
+ CTime: Cardinal;
+ CTime_hold: Cardinal;
+ ESC_Alpha: Integer;
+
+ credits_entry_tex: TTexture;
+ credits_entry_dx_tex: TTexture;
+ credits_bg_tex: TTexture;
+ credits_bg_ovl: TTexture;
+// credits_bg_logo: TTexture;
+ credits_bg_scrollbox_left: TTexture;
+ credits_blindguard: TTexture;
+ credits_blindy: TTexture;
+ credits_canni: TTexture;
+ credits_commandio: TTexture;
+ credits_lazyjoker: TTexture;
+ credits_mog: TTexture;
+ credits_mota: TTexture;
+ credits_skillmaster: TTexture;
+ credits_whiteshark: TTexture;
+ intro_layer01: TTexture;
+ intro_layer02: TTexture;
+ intro_layer03: TTexture;
+ intro_layer04: TTexture;
+ intro_layer05: TTexture;
+ intro_layer06: TTexture;
+ intro_layer07: TTexture;
+ intro_layer08: TTexture;
+ intro_layer09: TTexture;
+ outro_bg: TTexture;
+ outro_esc: TTexture;
+ outro_exd: TTexture;
+
+ deluxe_slidein: cardinal;
+
+ CurrentScrollText: String;
+ NextScrollUpdate: Real;
+ EndofLastScrollingPart: Cardinal;
+ CurrentScrollStart, CurrentScrollEnd: Integer;
+
+ CRDTS_Stage: TCreditsStages;
+
+ myTex: glUint;
+ mysdlimage,myconvertedsdlimage: PSDL_Surface;
+
+ Fadeout: boolean;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure DrawCredits;
+ procedure Draw_FunkyText;
+ end;
+
+const
+ Funky_Text: AnsiString =
+ 'Grandma Deluxe has arrived! Thanks to Corvus5 for the massive work on UltraStar, Wome for the nice tune you´re hearing, '+
+ 'all the people who put massive effort and work in new songs (don´t forget UltraStar w/o songs would be nothing), ppl from '+
+ 'irc helping us - eBandit and Gabari, scene ppl who really helped instead of compiling and running away. Greetings to DennisTheMenace for betatesting, '+
+ 'Demoscene.tv, pouet.net, KakiArts, Sourceforge,..';
+
+
+ Timings: array[0..21] of Cardinal=(
+ 20, // 0 Delay vor Start
+
+ 149, // 1 Ende erster Intro Zoom
+ 155, // 2 Start 2. Action im Intro
+ 170, // 3 Ende Separation im Intro
+ 271, // 4 Anfang Zoomout im Intro
+ 0, // 5 unused
+ 261, // 6 Start fade-to-white im Intro
+
+ 271, // 7 Start Main Part
+ 280, // 8 Start On-Beat-Sternchen Main Part
+
+ 396, // 9 Start BlindGuard
+ 666, // 10 Start blindy
+ 936, // 11 Start Canni
+ 1206, // 12 Start Commandio
+ 1476, // 13 Start LazyJoker
+ 1746, // 14 Start Mog
+ 2016, // 15 Start Mota
+ 2286, // 16 Start SkillMaster
+ 2556, // 17 Start WhiteShark
+ 2826, // 18 Ende Whiteshark
+ 3096, // 19 Start FadeOut Mainscreen
+ 3366, // 20 Ende Credits Tune
+ 60); // 21 start flare im intro
+
+
+ sdl32bpprgba: TSDL_Pixelformat=(palette: nil;
+ BitsPerPixel: 32;
+ BytesPerPixel: 4;
+ Rloss: 0;
+ Gloss: 0;
+ Bloss: 0;
+ Aloss: 0;
+ Rshift: 0;
+ Gshift: 8;
+ Bshift: 16;
+ Ashift: 24;
+ Rmask: $000000ff;
+ Gmask: $0000ff00;
+ Bmask: $00ff0000;
+ Amask: $ff000000;
+ colorkey: 0;
+ alpha: 255 );
+
+
+implementation
+
+uses {$IFDEF win32}
+ windows,
+ {$ELSE}
+ lclintf,
+ {$ENDIF}
+ ULog,
+ UGraphic,
+ UMain,
+ UIni,
+ USongs,
+ Textgl,
+ ULanguage,
+ UCommon,
+ Math,
+ dialogs;
+
+
+function TScreenCredits.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ FadeTo(@ScreenMain);
+ AudioPlayback.PlaySound(SoundLib.Back);
+ end;
+{ SDLK_SPACE:
+ begin
+ setlength(CTime_hold,length(CTime_hold)+1);
+ CTime_hold[high(CTime_hold)]:=CTime;
+ end;
+}
+ end;//esac
+ end; //fi
+end;
+
+constructor TScreenCredits.Create;
+begin
+ inherited Create;
+
+ credits_bg_tex := Texture.LoadTexture(true, 'CRDTS_BG', 'PNG', 'Plain', 0);
+ credits_bg_ovl := Texture.LoadTexture(true, 'CRDTS_OVL', 'PNG', 'Transparent', 0);
+
+ credits_blindguard := Texture.LoadTexture(true, 'CRDTS_blindguard', 'PNG', 'Font Black', 0);
+ credits_blindy := Texture.LoadTexture(true, 'CRDTS_blindy', 'PNG', 'Font Black', 0);
+ credits_canni := Texture.LoadTexture(true, 'CRDTS_canni', 'PNG', 'Font Black', 0);
+ credits_commandio := Texture.LoadTexture(true, 'CRDTS_commandio', 'PNG', 'Font Black', 0);
+ credits_lazyjoker := Texture.LoadTexture(true, 'CRDTS_lazyjoker', 'PNG', 'Font Black', 0);
+ credits_mog := Texture.LoadTexture(true, 'CRDTS_mog', 'PNG', 'Font Black', 0);
+ credits_mota := Texture.LoadTexture(true, 'CRDTS_mota', 'PNG', 'Font Black', 0);
+ credits_skillmaster := Texture.LoadTexture(true, 'CRDTS_skillmaster', 'PNG', 'Font Black', 0);
+ credits_whiteshark := Texture.LoadTexture(true, 'CRDTS_whiteshark', 'PNG', 'Font Black', 0);
+
+ intro_layer01 := Texture.LoadTexture(true, 'INTRO_L01', 'PNG', 'Transparent', 0);
+ intro_layer02 := Texture.LoadTexture(true, 'INTRO_L02', 'PNG', 'Transparent', 0);
+ intro_layer03 := Texture.LoadTexture(true, 'INTRO_L03', 'PNG', 'Transparent', 0);
+ intro_layer04 := Texture.LoadTexture(true, 'INTRO_L04', 'PNG', 'Transparent', 0);
+ intro_layer05 := Texture.LoadTexture(true, 'INTRO_L05', 'PNG', 'Transparent', 0);
+ intro_layer06 := Texture.LoadTexture(true, 'INTRO_L06', 'PNG', 'Transparent', 0);
+ intro_layer07 := Texture.LoadTexture(true, 'INTRO_L07', 'PNG', 'Transparent', 0);
+ intro_layer08 := Texture.LoadTexture(true, 'INTRO_L08', 'PNG', 'Transparent', 0);
+ intro_layer09 := Texture.LoadTexture(true, 'INTRO_L09', 'PNG', 'Transparent', 0);
+
+ outro_bg := Texture.LoadTexture(true, 'OUTRO_BG', 'PNG', 'Plain', 0);
+ outro_esc := Texture.LoadTexture(true, 'OUTRO_ESC', 'PNG', 'Transparent', 0);
+ outro_exd := Texture.LoadTexture(true, 'OUTRO_EXD', 'PNG', 'Transparent', 0);
+
+ CRDTS_Stage:=InitialDelay;
+end;
+
+function TScreenCredits.Draw: boolean;
+begin
+ DrawCredits;
+ Draw:=true;
+end;
+
+function pixfmt_eq(fmt1,fmt2: TSDL_Pixelformat): boolean;
+begin
+ if (fmt1.BitsPerPixel = fmt2.BitsPerPixel) and
+ (fmt1.BytesPerPixel = fmt2.BytesPerPixel) and
+ (fmt1.Rloss = fmt2.Rloss) and
+ (fmt1.Gloss = fmt2.Gloss) and
+ (fmt1.Bloss = fmt2.Bloss) and
+ (fmt1.Rmask = fmt2.Rmask) and
+ (fmt1.Gmask = fmt2.Gmask) and
+ (fmt1.Bmask = fmt2.Bmask) and
+ (fmt1.Rshift = fmt2.Rshift) and
+ (fmt1.Gshift = fmt2.Gshift) and
+ (fmt1.Bshift = fmt2.Bshift)
+ then
+ pixfmt_eq:=True
+ else
+ pixfmt_eq:=False;
+end;
+
+function inttohexstr(i: cardinal):pchar;
+var helper, i2, c:cardinal;
+ tmpstr: string;
+begin
+ helper:=0;
+ i2:=i;
+ tmpstr:='';
+ for c:=1 to 8 do
+ begin
+ helper:=(helper shl 4) or (i2 and $f);
+ i2:=i2 shr 4;
+ end;
+ for c:=1 to 8 do
+ begin
+ i2:=helper and $f;
+ helper := helper shr 4;
+ case i2 of
+ 0: tmpstr:=tmpstr+'0';
+ 1: tmpstr:=tmpstr+'1';
+ 2: tmpstr:=tmpstr+'2';
+ 3: tmpstr:=tmpstr+'3';
+ 4: tmpstr:=tmpstr+'4';
+ 5: tmpstr:=tmpstr+'5';
+ 6: tmpstr:=tmpstr+'6';
+ 7: tmpstr:=tmpstr+'7';
+ 8: tmpstr:=tmpstr+'8';
+ 9: tmpstr:=tmpstr+'9';
+ 10: tmpstr:=tmpstr+'a';
+ 11: tmpstr:=tmpstr+'b';
+ 12: tmpstr:=tmpstr+'c';
+ 13: tmpstr:=tmpstr+'d';
+ 14: tmpstr:=tmpstr+'e';
+ 15: tmpstr:=tmpstr+'f';
+ end;
+ end;
+ inttohexstr:=pchar(tmpstr);
+end;
+
+procedure TScreenCredits.onShow;
+begin
+ CRDTS_Stage:=InitialDelay;
+ Credits_X := 580;
+ deluxe_slidein := 0;
+ Credits_Alpha := 0;
+ //Music.SetLoop(true); Loop looped ned, so ne scheisse
+ AudioPlayback.Open(soundpath + 'wome-credits-tune.mp3'); //danke kleinster liebster weeeetüüüüü!!
+// Music.Play;
+ CTime:=0;
+// setlength(CTime_hold,0);
+
+ mysdlimage:=IMG_Load('test.png');
+ if assigned(mysdlimage) then
+ begin
+ {$IFNDEF FPC}
+ showmessage('opened image via SDL_Image'+#13#10+
+ 'Width: '+inttostr(mysdlimage^.w)+#13#10+
+ 'Height: '+inttostr(mysdlimage^.h)+#13#10+
+ 'BitsPP: '+inttostr(mysdlimage^.format.BitsPerPixel)+#13#10+
+ 'BytesPP: '+inttostr(mysdlimage^.format.BytesPerPixel)+#13#10+
+ 'Rloss: '+inttostr(mysdlimage^.format.Rloss)+#13#10+
+ 'Gloss: '+inttostr(mysdlimage^.format.Gloss)+#13#10+
+ 'Bloss: '+inttostr(mysdlimage^.format.Bloss)+#13#10+
+ 'Aloss: '+inttostr(mysdlimage^.format.Aloss)+#13#10+
+ 'Rshift: '+inttostr(mysdlimage^.format.Rshift)+#13#10+
+ 'Gshift: '+inttostr(mysdlimage^.format.Gshift)+#13#10+
+ 'Bshift: '+inttostr(mysdlimage^.format.Bshift)+#13#10+
+ 'Ashift: '+inttostr(mysdlimage^.format.Ashift)+#13#10+
+ 'Rmask: '+inttohexstr(mysdlimage^.format.Rmask)+#13#10+
+ 'Gmask: '+inttohexstr(mysdlimage^.format.Gmask)+#13#10+
+ 'Bmask: '+inttohexstr(mysdlimage^.format.Bmask)+#13#10+
+ 'Amask: '+inttohexstr(mysdlimage^.format.Amask)+#13#10+
+ 'ColKey: '+inttostr(mysdlimage^.format.Colorkey)+#13#10+
+ 'Alpha: '+inttostr(mysdlimage^.format.Alpha));
+
+ if pixfmt_eq(mysdlimage^.format^,sdl32bpprgba) then
+ showmessage('equal pixelformats')
+ else
+ showmessage('different pixelformats');
+ {$ENDIF}
+
+ myconvertedsdlimage:=SDL_ConvertSurface(mysdlimage,@sdl32bpprgba,SDL_SWSURFACE);
+ glGenTextures(1,@myTex);
+ glBindTexture(GL_TEXTURE_2D, myTex);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexImage2D( GL_TEXTURE_2D, 0, 4, myconvertedsdlimage^.w, myconvertedsdlimage^.h, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, myconvertedsdlimage^.pixels );
+ SDL_FreeSurface(mysdlimage);
+ SDL_FreeSurface(myconvertedsdlimage);
+ end
+ else
+ {$IFDEF FPC}
+ writeln( 'could not open file - test.png');
+ {$ELSE}
+ showmessage('could not open file - test.png');
+ {$ENDIF}
+
+end;
+
+procedure TScreenCredits.onHide;
+begin
+ AudioPlayback.Stop;
+end;
+
+Procedure TScreenCredits.Draw_FunkyText;
+var
+ S: Integer;
+ X,Y,A: Real;
+ visibleText: PChar;
+begin
+ SetFontSize(10);
+ //Init ScrollingText
+ if (CTime = Timings[7]) then
+ begin
+ //Set Position of Text
+ Credits_X := 600;
+ CurrentScrollStart:=1;
+ CurrentScrollEnd:=1;
+ end;
+
+ if (CTime > Timings[7]) and (CurrentScrollStart < length(Funky_Text)) then
+ begin
+ X:=0;
+ visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
+ for S := 0 to length(visibleText)-1 do begin
+ Y:=abs(sin((Credits_X+X)*0.93{*(((Credits_X+X))/1200)}/100*pi));
+ SetFontPos(Credits_X+X,538-Y*(Credits_X+X)*(Credits_X+X)*(Credits_X+X)/1000000);
+ A:=0;
+ if (Credits_X+X < 15) then A:=0;
+ if (Credits_X+X >=15) then A:=Credits_X+X-15;
+ if Credits_X+X > 32 then A:=17;
+ glColor4f( 230/255-40/255+Y*(Credits_X+X)/900, 200/255-30/255+Y*(Credits_X+X)/1000, 155/255-20/255+Y*(Credits_X+X)/1100, A/17);
+ glPrintLetter(visibleText[S]);
+ X := X + Fonts[ActFont].Width[Ord(visibleText[S])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
+ end;
+ if (Credits_X<0) and (CurrentScrollStart < length(Funky_Text)) then begin
+ Credits_X:=Credits_X + Fonts[ActFont].Width[Ord(Funky_Text[CurrentScrollStart])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
+ inc(CurrentScrollStart);
+ end;
+ visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
+ if (Credits_X+glTextWidth(visibleText) < 600) and (CurrentScrollEnd < length(Funky_Text)) then begin
+ inc(CurrentScrollEnd);
+ end;
+ end;
+{ // timing hack
+ X:=5;
+ SetFontStyle (2);
+ SetFontItalic(False);
+ SetFontSize(9);
+ glColor4f(1, 1, 1, 1);
+ for S:=0 to high(CTime_hold) do begin
+ visibleText:=pchar(inttostr(CTime_hold[S]));
+ SetFontPos (500, X);
+ glPrint (Addr(visibleText[0]));
+ X:=X+20;
+ end;}
+end;
+
+procedure Start3D;
+begin
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix;
+ glLoadIdentity;
+ glFrustum(-0.3*4/3,0.3*4/3,-0.3,0.3,1,1000);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity;
+end;
+procedure End3D;
+begin
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix;
+ glMatrixMode(GL_MODELVIEW);
+end;
+
+procedure TScreenCredits.DrawCredits;
+var
+ T,I: Cardinal;
+ X: Real;
+ Ver: PChar;
+ RuntimeStr: AnsiString;
+ Data: TFFTData;
+ j,k,l:cardinal;
+ f,g,h: Real;
+ STime:cardinal;
+ Delay:cardinal;
+
+ myPixel: longword;
+ myColor: Cardinal;
+ myScale: Real;
+ myAngle: Real;
+
+
+const myLogoCoords: Array[0..27,0..1] of Cardinal = ((39,32),(84,32),(100,16),(125,24),
+ (154,31),(156,58),(168,32),(203,36),
+ (258,34),(251,50),(274,93),(294,84),
+ (232,54),(278,62),(319,34),(336,92),
+ (347,23),(374,32),(377,58),(361,83),
+ (385,91),(405,91),(429,35),(423,51),
+ (450,32),(485,34),(444,91),(486,93));
+
+begin
+ //dis does teh muiwk y0r
+ AudioPlayback.GetFFTData(Data);
+
+ Log.LogStatus('',' JB-1');
+
+ T := GetTickCount div 33;
+ if T <> Credits_Time then
+ begin
+ Credits_Time := T;
+ inc(CTime);
+ inc(CTime_hold);
+ Credits_X := Credits_X-2;
+
+ Log.LogStatus('',' JB-2');
+ if (CRDTS_Stage=InitialDelay) and (CTime=Timings[0]) then
+ begin
+// CTime:=Timings[20];
+// CRDTS_Stage:=Outro;
+
+ CRDTS_Stage:=Intro;
+ CTime:=0;
+ AudioPlayback.Play;
+
+ end;
+ if (CRDTS_Stage=Intro) and (CTime=Timings[7]) then
+ begin
+ CRDTS_Stage:=MainPart;
+ end;
+ if (CRDTS_Stage=MainPart) and (CTime=Timings[20]) then
+ begin
+ CRDTS_Stage:=Outro;
+ end;
+ end;
+
+ Log.LogStatus('',' JB-3');
+
+ //draw background
+ if CRDTS_Stage=InitialDelay then
+ begin
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end
+ else
+ if CRDTS_Stage=Intro then
+ begin
+ Start3D;
+ glPushMatrix;
+
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ if CTime < Timings[1] then begin
+ myScale:= 0.5+0.5*(Timings[1]-CTime)/(Timings[1]); // slowly move layers together
+ myAngle:=cos((CTime)*pi/((Timings[1])*2)); // and make logo face towards camera
+ end else begin // this is the part when the logo stands still
+ myScale:=0.5;
+ myAngle:=0;
+ end;
+ if CTime > Timings[2] then begin
+ myScale:= 0.5+0.5*(CTime-Timings[2])/(Timings[3]-Timings[2]); // get some space between layers
+ myAngle:=0;
+ end;
+// if CTime > Timings[3] then myScale:=1; // keep the space between layers
+ glTranslatef(0,0,-5+0.5*myScale);
+ if CTime > Timings[3] then myScale:=1; // keep the space between layers
+ if CTime > Timings[3] then begin // make logo rotate left and grow
+// myScale:=(CTime-Timings[4])/(Timings[7]-Timings[4]);
+ glRotatef(20*sqr(CTime-Timings[3])/sqr((Timings[7]-Timings[3])/2),0,0,1);
+ glScalef(1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1);
+ end;
+ if CTime < Timings[2] then
+ glRotatef(30*myAngle,0.5*myScale+myScale,1+myScale,0);
+// glScalef(0.5,0.5,0.5);
+ glScalef(4/3,-1,1);
+ glColor4f(1, 1, 1, 1);
+
+ glBindTexture(GL_TEXTURE_2D, intro_layer01.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.4 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.4 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.4 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.4 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer02.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.3 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.3 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.3 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.3 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer03.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.2 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.2 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.2 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.2 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer04.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.1 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.1 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.1 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.1 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer05.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer06.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.1 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.1 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.1 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.1 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer07.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.2 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.2 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.2 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.2 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer08.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.3 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.3 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.3 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.3 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer09.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.22 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.22 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.22 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.22 * myScale);
+ glEnd;
+ gldisable(gl_texture_2d);
+ glDisable(GL_BLEND);
+
+ glPopMatrix;
+ End3D;
+
+ // do some sparkling effects
+ if (CTime < Timings[1]) and (CTime > Timings[21]) then
+ begin
+ for k:=1 to 3 do begin
+ l:=410+floor((CTime-Timings[21])/(Timings[1]-Timings[21])*(536-410))+RandomRange(-5,5);
+ j:=floor((Timings[1]-CTime)/22)+RandomRange(285,301);
+ GoldenRec.Spawn(l, j, 1, 16, 0, -1, Flare, 0);
+ end;
+ end;
+
+ // fade to white at end
+ if Ctime > Timings[6] then
+ begin
+ glColor4f(1,1,1,sqr(Ctime-Timings[6])*(Ctime-Timings[6])/sqr(Timings[7]-Timings[6]));
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0,0);
+ glVertex2f(0,600);
+ glVertex2f(800,600);
+ glVertex2f(800,0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+
+ end;
+ if (CRDTS_Stage=MainPart) then
+ // main credits screen background, scroller, logo and girl
+ begin
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, credits_bg_tex.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(0, 600);
+ glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(800/1024,0);glVertex2f(800, 0);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ // draw scroller
+ Draw_FunkyText;
+
+//#########################################################################
+// draw credits names
+
+
+Log.LogStatus('',' JB-4');
+
+// BlindGuard (von links oben reindrehen, nach rechts unten rausdrehen)
+ STime:=Timings[9]-10;
+ Delay:=Timings[10]-Timings[9];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(0,329,0);
+ if CTime <= STime+10 then begin glrotatef((CTime-STime)*9+270,0,0,1);end;
+ gltranslatef(223,0,0);
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ gltranslatef(223,0,0);
+ glrotatef((integer(CTime)-(integer(STime+Delay)-10))*-9,0,0,1);
+ gltranslatef(-223,0,0);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_blindguard.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Blindy (zoom von 0 auf volle grösse und drehung, zoom auf doppelte grösse und nach rechts oben schieben)
+ STime:=Timings[10]-10;
+ Delay:=Timings[11]-Timings[10]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+20) and (CTime<=STime+22) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+20 then begin
+ j:=CTime-Stime;
+ glscalef(j*j/400,j*j/400,j*j/400);
+ glrotatef(j*18.0,0,0,1);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ f:=j*10.0;
+ gltranslatef(f*3,-f,0);
+ glscalef(1+j/10,1+j/10,1+j/10);
+ glrotatef(j*9.0,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_blindy.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Canni (von links reinschieben, nach rechts oben rausschieben)
+ STime:=Timings[11]-10;
+ Delay:=Timings[12]-Timings[11]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ gltranslatef(((CTime-STime)*21.0)-210,0,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=(CTime-(STime+Delay-10))*21;
+ gltranslatef(j,-j/2,0);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_canni.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Commandio (von unten reinklappen, nach rechts oben rausklappen)
+ STime:=Timings[12]-10;
+ Delay:=Timings[13]-Timings[12];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=258.0-25.8*(CTime-STime)
+ else
+ f:=0;
+ g:=0;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_commandio.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163+g-f*1.5, -129+f*1.5-g/2);
+ glTexCoord2f(0,1);glVertex2f(-163+g*1.5, 129-(g*1.5*258/326));
+ glTexCoord2f(1,1); glVertex2f(163+g, 129+g/4);
+ glTexCoord2f(1,0);glVertex2f(163+f*1.5+g/4, -129+f*1.5-g/4);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// lazy joker (just scrolls from left to right, no twinkling stars, no on-beat flashing)
+ STime:=Timings[13]-35;
+ Delay:=Timings[14]-Timings[13]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)>10) and ((CTime-STime)<20) then ESC_Alpha:=20;
+ ESC_Alpha:=10;
+ f:=CTime-STime;
+ if CTime <=STime+40 then j:=CTime-STime else j:=40;
+ if (CTime >=STime+Delay-40) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j*j/1600);
+
+ glPushMatrix;
+ gltranslatef(180+(f-70),329,0);
+ glBindTexture(GL_TEXTURE_2D, credits_lazyjoker.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Mog (von links reinklappen, nach rechts unten rausklappen)
+ STime:=Timings[14]-10;
+ Delay:=Timings[15]-Timings[14]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=326.0-32.6*(CTime-STime)
+ else
+ f:=0;
+
+ g:=0;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_mog.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163+g*1.5, -129+g*1.5);
+ glTexCoord2f(0,1);glVertex2f(-163+g*1.2, 129+g);
+ glTexCoord2f(1,1); glVertex2f(163-f+g/2, 129+f*1.5+g/4);
+ glTexCoord2f(1,0);glVertex2f(163-f+g*1.5, -129-f*1.5);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Mota (von rechts oben reindrehen, nach links unten rausschieben und verkleinern und dabei drehen)
+ STime:=Timings[15]-10;
+ Delay:=Timings[16]-Timings[15]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ gltranslatef(223,0,0);
+ glrotatef((10-(CTime-STime))*9,0,0,1);
+ gltranslatef(-223,0,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ f:=j*10.0;
+ gltranslatef(-f*2,-f,0);
+ glscalef(1-j/10,1-j/10,1-j/10);
+ glrotatef(-j*9.0,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_mota.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Skillmaster (von rechts unten reinschieben, nach rechts oben rausdrehen)
+ STime:=Timings[16]-10;
+ Delay:=Timings[17]-Timings[16]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ j:=STime+10-CTime;
+ f:=j*10.0;
+ gltranslatef(+f*2,+f/2,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ gltranslatef(0,-223,0);
+ glrotatef(integer(j)*-9,0,0,1);
+ gltranslatef(0,223,0);
+ glrotatef(j*9,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_skillmaster.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// WhiteShark (von links unten reinklappen, nach rechts oben rausklappen)
+ STime:=Timings[17]-10;
+ Delay:=Timings[18]-Timings[17];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=326.0-32.6*(CTime-STime)
+ else
+ f:=0;
+
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end else
+ g:=0;
+ glBindTexture(GL_TEXTURE_2D, credits_whiteshark.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163-f+g, -129+f/4-g/2);
+ glTexCoord2f(0,1);glVertex2f(-163-f/4+g, 129+g/2+f/4);
+ glTexCoord2f(1,1); glVertex2f(163-f*1.2+g/4, 129+f/2-g/4);
+ glTexCoord2f(1,0);glVertex2f(163-f*1.5+g/4, -129+f*1.5+g/4);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+
+ Log.LogStatus('',' JB-103');
+
+// ####################################################################
+// do some twinkle stuff (kinda on beat)
+ if (CTime > Timings[8] ) and
+ (CTime < Timings[19] ) then
+ begin
+ k := 0;
+
+ try
+ for j:=0 to 40 do
+ begin
+ if ( j < length( Data ) ) AND
+ ( k < length( Data ) ) then
+ begin
+ if Data[j] >= Data[k] then
+ k:=j;
+ end;
+ end;
+ except
+ end;
+
+ if Data[k]>0.2 then
+ begin
+ l := RandomRange(6,16);
+ j := RandomRange(0,27);
+
+ GoldenRec.Spawn(myLogoCoords[j,0], myLogoCoords[j,1], 16-l, l, 0, -1, PerfectNote, 0);
+ end;
+ end;
+
+//#################################################
+// draw the rest of the main screen (girl and logo
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, credits_bg_ovl.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(800-393, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(800-393, 600);
+ glTexCoord2f(393/512,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(393/512,0);glVertex2f(800, 0);
+ glEnd;
+{ glBindTexture(GL_TEXTURE_2D, credits_bg_logo.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,112/128);glVertex2f(0, 112);
+ glTexCoord2f(497/512,112/128); glVertex2f(497, 112);
+ glTexCoord2f(497/512,0);glVertex2f(497, 0);
+ glEnd;
+}
+ gldisable(gl_texture_2d);
+ glDisable(GL_BLEND);
+
+ // fade out at end of main part
+ if Ctime > Timings[19] then
+ begin
+ glColor4f(0,0,0,(Ctime-Timings[19])/(Timings[20]-Timings[19]));
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0,0);
+ glVertex2f(0,600);
+ glVertex2f(800,600);
+ glVertex2f(800,0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+ end
+ else
+ if (CRDTS_Stage=Outro) then
+ begin
+ if CTime=Timings[20] then begin
+ CTime_hold:=0;
+ AudioPlayback.Stop;
+ AudioPlayback.Open(soundpath + 'credits-outro-tune.mp3');
+ AudioPlayback.Play;
+ AudioPlayback.SetVolume(20);
+ AudioPlayback.SetLoop(True);
+ end;
+ if CTime_hold > 231 then begin
+ AudioPlayback.Play;
+ Ctime_hold:=0;
+ end;
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ // do something useful
+ // outro background
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, outro_bg.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(0, 600);
+ glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(800/1024,0);glVertex2f(800, 0);
+ glEnd;
+
+ //outro overlays
+ glColor4f(1, 1, 1, (1+sin(CTime/15))/3+1/3);
+ glBindTexture(GL_TEXTURE_2D, outro_esc.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,223/256);glVertex2f(0, 223);
+ glTexCoord2f(487/512,223/256); glVertex2f(487, 223);
+ glTexCoord2f(487/512,0);glVertex2f(487, 0);
+ glEnd;
+
+ ESC_Alpha:=20;
+ if (RandomRange(0,20) > 18) and (ESC_Alpha=20) then
+ ESC_Alpha:=0
+ else inc(ESC_Alpha);
+ if ESC_Alpha > 20 then ESC_Alpha:=20;
+ glColor4f(1, 1, 1, ESC_Alpha/20);
+ glBindTexture(GL_TEXTURE_2D, outro_exd.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(800-310, 600-247);
+ glTexCoord2f(0,247/256);glVertex2f(800-310, 600);
+ glTexCoord2f(310/512,247/256); glVertex2f(800, 600);
+ glTexCoord2f(310/512,0);glVertex2f(800, 600-247);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ // outro scrollers?
+ // ...
+ end;
+
+{ // draw credits runtime counter
+ SetFontStyle (2);
+ SetFontItalic(False);
+ SetFontSize(9);
+ SetFontPos (5, 5);
+ glColor4f(1, 1, 1, 1);
+// RuntimeStr:='CTime: '+inttostr(floor(CTime/30.320663991914489602156136106092))+'.'+inttostr(floor(CTime/3.0320663991914489602156136106092)-floor(CTime/30.320663991914489602156136106092)*10);
+ RuntimeStr:='CTime: '+inttostr(CTime);
+ glPrint (Addr(RuntimeStr[1]));
+}
+
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, myTex);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(100, 100);
+ glTexCoord2f(0,1);glVertex2f(100, 200);
+ glTexCoord2f(1,1); glVertex2f(200, 200);
+ glTexCoord2f(1,0);glVertex2f(200, 100);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+
+ // make the stars shine
+ GoldenRec.Draw;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenEdit.pas b/Game/Code/Screens/UScreenEdit.pas index 49adb994..00feddbf 100644 --- a/Game/Code/Screens/UScreenEdit.pas +++ b/Game/Code/Screens/UScreenEdit.pas @@ -38,7 +38,7 @@ begin SDLK_ESCAPE,
SDLK_BACKSPACE :
begin
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenMain);
// Result := false;
end;
@@ -46,7 +46,7 @@ begin begin
if Interaction = 0 then
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenEditConvert);
end;
// if Interaction = 1 then begin
@@ -56,7 +56,7 @@ begin if Interaction = 1 then
begin
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenMain);
end;
end;
diff --git a/Game/Code/Screens/UScreenEditConvert.pas b/Game/Code/Screens/UScreenEditConvert.pas index a523afd2..304c2259 100644 --- a/Game/Code/Screens/UScreenEditConvert.pas +++ b/Game/Code/Screens/UScreenEditConvert.pas @@ -121,7 +121,7 @@ begin {$IFDEF UseMIDIPort} MidiFile.StopPlaying; {$ENDIF} - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenEdit); end; @@ -129,7 +129,7 @@ begin begin if Interaction = 0 then begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); ScreenOpen.BackScreen := @ScreenEditConvert; FadeTo(@ScreenOpen); end; diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas index 57d6777e..4d971c63 100644 --- a/Game/Code/Screens/UScreenEditSub.pas +++ b/Game/Code/Screens/UScreenEditSub.pas @@ -1277,7 +1277,7 @@ begin for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin - AudioPlayback.PlayClick; + AudioPlayback.PlaySound(SoundLib.Click); LastClick := AktBeat; end; end; diff --git a/Game/Code/Screens/UScreenLevel.pas b/Game/Code/Screens/UScreenLevel.pas index e5deb6ba..16e24027 100644 --- a/Game/Code/Screens/UScreenLevel.pas +++ b/Game/Code/Screens/UScreenLevel.pas @@ -38,7 +38,7 @@ begin SDLK_ESCAPE,
SDLK_BACKSPACE :
begin
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenName);
end;
@@ -46,7 +46,7 @@ begin begin
Ini.Difficulty := Interaction;
Ini.SaveLevel;
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
//Set Standard Mode
ScreenSong.Mode := smNormal;
FadeTo(@ScreenSong);
diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas index a4dc5f0d..5824d9fe 100644 --- a/Game/Code/Screens/UScreenMain.pas +++ b/Game/Code/Screens/UScreenMain.pas @@ -94,7 +94,7 @@ begin //Credits_Y := 600; //Credits_Alpha := 0; //Credits_Visible := True; - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); FadeTo(@ScreenCredits); end; end; @@ -102,20 +102,20 @@ begin begin if (Ini.Players >= 1) AND (Length(DLLMan.Plugins)>=1) then begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); FadeTo(@ScreenPartyOptions); end; end; SDLK_S: begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); FadeTo(@ScreenStatMain); end; SDLK_E: begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); FadeTo(@ScreenEdit); end; @@ -126,7 +126,7 @@ begin begin if (Songs.SongList.Count >= 1) then begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); if (Ini.Players >= 0) and (Ini.Players <= 3) then PlayersPlay := Ini.Players + 1; if (Ini.Players = 4) then PlayersPlay := 6; @@ -144,7 +144,7 @@ begin begin if (Length(DLLMan.Plugins)>=1) then begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); FadeTo(@ScreenPartyOptions); end else //show error message, No Plugins Loaded @@ -157,21 +157,21 @@ begin //Stats if Interaction = 2 then begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); FadeTo(@ScreenStatMain); end; //Editor if Interaction = 3 then begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); FadeTo(@ScreenEdit); end; //Options if Interaction = 4 then begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); FadeTo(@ScreenOptions); end; diff --git a/Game/Code/Screens/UScreenName.pas b/Game/Code/Screens/UScreenName.pas index 76e79a3b..f33d6409 100644 --- a/Game/Code/Screens/UScreenName.pas +++ b/Game/Code/Screens/UScreenName.pas @@ -158,7 +158,7 @@ begin SDLK_ESCAPE :
begin
Ini.SaveNames;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
if GoTo_SingScreen then
FadeTo(@ScreenSong)
else
@@ -170,7 +170,7 @@ begin for I := 1 to 6 do
Ini.Name[I-1] := Button[I-1].Text[0].Text;
Ini.SaveNames;
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
if GoTo_SingScreen then
FadeTo(@ScreenSing)
diff --git a/Game/Code/Screens/UScreenOpen.pas b/Game/Code/Screens/UScreenOpen.pas index 30404d6e..5d78fb31 100644 --- a/Game/Code/Screens/UScreenOpen.pas +++ b/Game/Code/Screens/UScreenOpen.pas @@ -59,7 +59,7 @@ begin begin
//Empty Filename and go to last Screen
FileName := '';
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(BackScreen);
end;
@@ -68,14 +68,14 @@ begin if (Interaction = 2) then begin
//Update Filename and go to last Screen
FileName := Text[TextN].Text;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(BackScreen);
end
else if (Interaction = 1) then
begin
//Empty Filename and go to last Screen
FileName := '';
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(BackScreen);
end;
end;
diff --git a/Game/Code/Screens/UScreenOptions.pas b/Game/Code/Screens/UScreenOptions.pas index bcd781cc..4e39fe21 100644 --- a/Game/Code/Screens/UScreenOptions.pas +++ b/Game/Code/Screens/UScreenOptions.pas @@ -38,57 +38,57 @@ begin SDLK_BACKSPACE :
begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenMain);
end;
SDLK_RETURN:
begin
if SelInteraction = 0 then
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenOptionsGame);
end;
if SelInteraction = 1 then
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenOptionsGraphics);
end;
if SelInteraction = 2 then
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenOptionsSound);
end;
if SelInteraction = 3 then
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenOptionsLyrics);
end;
if SelInteraction = 4 then
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenOptionsThemes);
end;
if SelInteraction = 5 then
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenOptionsRecord);
end;
if SelInteraction = 6 then
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenOptionsAdvanced);
end;
if SelInteraction = 7 then
begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenMain);
end;
end;
diff --git a/Game/Code/Screens/UScreenOptionsAdvanced.pas b/Game/Code/Screens/UScreenOptionsAdvanced.pas index 0d40b7ec..e2c30bf1 100644 --- a/Game/Code/Screens/UScreenOptionsAdvanced.pas +++ b/Game/Code/Screens/UScreenOptionsAdvanced.pas @@ -34,7 +34,7 @@ begin SDLK_BACKSPACE :
begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenOptions);
end;
SDLK_RETURN:
@@ -43,7 +43,7 @@ begin //if SelInteraction = 7 then begin
if SelInteraction = 6 then begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenOptions);
end;
end;
@@ -56,7 +56,7 @@ begin //SelectLoadAnimation Hidden because it is useless atm
//if (SelInteraction >= 0) and (SelInteraction <= 6) then begin
if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractInc;
end;
end;
@@ -65,7 +65,7 @@ begin //SelectLoadAnimation Hidden because it is useless atm
//if (SelInteraction >= 0) and (SelInteraction <= 6) then begin
if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractDec;
end;
end;
diff --git a/Game/Code/Screens/UScreenOptionsGame.pas b/Game/Code/Screens/UScreenOptionsGame.pas index 6cd0a20c..15b538a5 100644 --- a/Game/Code/Screens/UScreenOptionsGame.pas +++ b/Game/Code/Screens/UScreenOptionsGame.pas @@ -35,14 +35,14 @@ begin SDLK_ESCAPE,
SDLK_BACKSPACE :
begin
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
RefreshSongs;
FadeTo(@ScreenOptions);
end;
SDLK_RETURN:
begin
if SelInteraction = 6 then begin
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
RefreshSongs;
FadeTo(@ScreenOptions);
end;
@@ -55,7 +55,7 @@ begin begin
if (SelInteraction >= 0) and (SelInteraction <= 5) then
begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractInc;
end;
end;
@@ -63,7 +63,7 @@ begin begin
if (SelInteraction >= 0) and (SelInteraction <= 5) then
begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractDec;
end;
end;
diff --git a/Game/Code/Screens/UScreenOptionsGraphics.pas b/Game/Code/Screens/UScreenOptionsGraphics.pas index 947d506b..4ceeeb32 100644 --- a/Game/Code/Screens/UScreenOptionsGraphics.pas +++ b/Game/Code/Screens/UScreenOptionsGraphics.pas @@ -34,7 +34,7 @@ begin SDLK_BACKSPACE :
begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenOptions);
end;
SDLK_RETURN:
@@ -44,7 +44,7 @@ begin end;}
if SelInteraction = 5 then begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenOptions);
end;
end;
@@ -55,14 +55,14 @@ begin SDLK_RIGHT:
begin
if (SelInteraction >= 0) and (SelInteraction <= 4) then begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractInc;
end;
end;
SDLK_LEFT:
begin
if (SelInteraction >= 0) and (SelInteraction <= 4) then begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractDec;
end;
end;
diff --git a/Game/Code/Screens/UScreenOptionsLyrics.pas b/Game/Code/Screens/UScreenOptionsLyrics.pas index 8d70eec9..7275efed 100644 --- a/Game/Code/Screens/UScreenOptionsLyrics.pas +++ b/Game/Code/Screens/UScreenOptionsLyrics.pas @@ -34,14 +34,14 @@ begin SDLK_BACKSPACE :
begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenOptions);
end;
SDLK_RETURN:
begin
if SelInteraction = 3 then begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenOptions);
end;
end;
@@ -52,14 +52,14 @@ begin SDLK_RIGHT:
begin
if (SelInteraction >= 0) and (SelInteraction <= 2) then begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractInc;
end;
end;
SDLK_LEFT:
begin
if (SelInteraction >= 0) and (SelInteraction <= 2) then begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractDec;
end;
end;
diff --git a/Game/Code/Screens/UScreenOptionsRecord.pas b/Game/Code/Screens/UScreenOptionsRecord.pas index 65d016c7..130c3551 100644 --- a/Game/Code/Screens/UScreenOptionsRecord.pas +++ b/Game/Code/Screens/UScreenOptionsRecord.pas @@ -1,212 +1,232 @@ -unit UScreenOptionsRecord; - -interface - -{$I switches.inc} - -uses - UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes; - -type - TScreenOptionsRecord = class(TMenu) - private - SelectSlideInput: integer; - SelectSlideChannelL: integer; - SelectSlideChannelR: integer; - public - constructor Create; override; - function Draw: boolean; override; - function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; - procedure onShow; override; - procedure onHide; override; - procedure UpdateCard; - end; - -implementation - -uses SysUtils, - UGraphic, - URecord, - UDraw, - UMain, - ULog; - -function TScreenOptionsRecord.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; -begin - Result := true; - If (PressedDown) Then - begin // Key Down - case PressedKey of - SDLK_Q: - begin - Result := false; - end; - SDLK_ESCAPE, - SDLK_BACKSPACE: - begin - Ini.Save; - AudioPlayback.PlayBack; - FadeTo(@ScreenOptions); - end; - SDLK_RETURN: - begin - if SelInteraction = 5 then begin - Ini.Save; - AudioPlayback.PlayBack; - FadeTo(@ScreenOptions); - end; - end; - SDLK_DOWN: - InteractNext; - SDLK_UP : - InteractPrev; - SDLK_RIGHT: - begin - if (SelInteraction >= 0) and (SelInteraction <= 4) then begin - AudioPlayback.PlayOption; - InteractInc; - end; -// if SelInteraction = 0 then UpdateCard; - UpdateCard; - end; - SDLK_LEFT: - begin - if (SelInteraction >= 0) and (SelInteraction <= 4) then begin - AudioPlayback.PlayOption; - InteractDec; - end; - UpdateCard; -// if SelInteraction = 0 then UpdateCard; - end; - end; - end; -end; - -constructor TScreenOptionsRecord.Create; -var - I: integer; - SC: integer; - SCI: integer; -begin - inherited Create; - - LoadFromTheme(Theme.OptionsRecord); - - SetLength(ICard, Length(AudioInputProcessor.SoundCard)); - for SC := 0 to High(AudioInputProcessor.SoundCard) do - ICard[SC] := AudioInputProcessor.SoundCard[SC].Description; - - if (Length(AudioInputProcessor.SoundCard) > 0) then - begin - SetLength(IInput, Length(AudioInputProcessor.SoundCard[Ini.Card].Input)); - for SCI := 0 to High(AudioInputProcessor.SoundCard[Ini.Card].Input) do - IInput[SCI] := AudioInputProcessor.SoundCard[Ini.Card].Input[SCI].Name; - - - AddSelectSlide(Theme.OptionsRecord.SelectSlideCard, Ini.Card, ICard); - - SelectSlideInput := AddSelectSlide(Theme.OptionsRecord.SelectSlideInput, Ini.CardList[0].Input, IInput); - SelectSlideChannelL := AddSelectSlide(Theme.OptionsRecord.SelectSlideChannelL, Ini.CardList[0].ChannelL, IChannel); - SelectSlideChannelR := AddSelectSlide(Theme.OptionsRecord.SelectSlideChannelR, Ini.CardList[0].ChannelR, IChannel); - - AddSelect(Theme.OptionsSound.SelectMicBoost, Ini.MicBoost, IMicBoost); - end; - - AddButton(Theme.OptionsRecord.ButtonExit); - if (Length(Button[0].Text)=0) then - AddButtonText(14, 20, Theme.Options.Description[7]); - - Interaction := 0; -end; - -procedure TScreenOptionsRecord.onShow; -begin - Interaction := 0; - writeln( 'AudioInput.CaptureStart') ; - - PlayersPlay := 2; // TODO : This needs fixing - AudioInput.CaptureStart; - -end; - -procedure TScreenOptionsRecord.onHide; -begin - AudioInput.CaptureStop; -end; - -procedure TScreenOptionsRecord.UpdateCard; -var - SC: integer; - SCI: integer; -begin - writeln( 'Update Card') ; - AudioInput.CaptureStop; - try - SC := Ini.Card; - // if SC = 1 then beep; - - SetLength(IInput, Length(AudioInputProcessor.SoundCard[SC].Input)); - for SCI := 0 to High(AudioInputProcessor.SoundCard[SC].Input) do begin - IInput[SCI] := AudioInputProcessor.SoundCard[SC].Input[SCI].Name; - // Log.LogError(IInput[SCI]); - end; - - - UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectSlideInput, IInput, Ini.CardList[SC].Input); - UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelL, SelectSlideChannelL, IChannel, Ini.CardList[SC].ChannelL); - UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelR, SelectSlideChannelR, IChannel, Ini.CardList[SC].ChannelR); - - finally - AudioInput.CaptureStart; - end; -end; - -function TScreenOptionsRecord.Draw: boolean; -begin - DrawBG; - DrawFG; - - // TODO : this needs to be positioned correctly - if PlayersPlay = 1 then - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - - if PlayersPlay = 2 then begin - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); - end; - - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); - end; - if ScreenAct = 2 then begin - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2); - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3); - end; - end; - - if PlayersPlay = 3 then begin - SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0); - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0); - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); - end; - if ScreenAct = 2 then begin - SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3); - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4); - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5); - end; - end; - - Result := True; -end; - - -end. +unit UScreenOptionsRecord;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
+
+type
+ TScreenOptionsRecord = class(TMenu)
+ private
+ Card: integer; // current input device
+
+ SelectSlideInput: integer;
+ SelectSlideChannelL: integer;
+ SelectSlideChannelR: integer;
+ public
+ constructor Create; override;
+ function Draw: boolean; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure UpdateCard;
+ end;
+
+implementation
+
+uses SysUtils,
+ UGraphic,
+ URecord,
+ UDraw,
+ UMain,
+ ULog;
+
+function TScreenOptionsRecord.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE:
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 5 then begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 4) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+// if SelInteraction = 0 then UpdateCard;
+ UpdateCard;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 4) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ UpdateCard;
+// if SelInteraction = 0 then UpdateCard;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsRecord.Create;
+var
+ SC: integer;
+ SCI: integer;
+ InputDevice: TAudioInputDevice;
+ InputDeviceCfg: PInputDeviceConfig;
+begin
+ inherited Create;
+
+ Card := 0;
+
+ LoadFromTheme(Theme.OptionsRecord);
+
+ SetLength(ICard, Length(AudioInputProcessor.Device));
+ for SC := 0 to High(AudioInputProcessor.Device) do
+ ICard[SC] := AudioInputProcessor.Device[SC].Description;
+
+ if (Card > High(AudioInputProcessor.Device)) then
+ Card := 0;
+
+ if (Length(AudioInputProcessor.Device) > 0) then
+ begin
+ InputDevice := AudioInputProcessor.Device[Card];
+ InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
+
+ SetLength(IInput, Length(InputDevice.Source));
+ for SCI := 0 to High(InputDevice.Source) do
+ IInput[SCI] := InputDevice.Source[SCI].Name;
+
+ AddSelectSlide(Theme.OptionsRecord.SelectSlideCard, Card, ICard);
+
+ SelectSlideInput := AddSelectSlide(Theme.OptionsRecord.SelectSlideInput,
+ InputDeviceCfg^.Input, IInput);
+ SelectSlideChannelL := AddSelectSlide(Theme.OptionsRecord.SelectSlideChannelL,
+ InputDeviceCfg^.ChannelToPlayerMap[0], IChannel);
+ SelectSlideChannelR := AddSelectSlide(Theme.OptionsRecord.SelectSlideChannelR,
+ InputDeviceCfg^.ChannelToPlayerMap[1], IChannel);
+
+ AddSelect(Theme.OptionsSound.SelectMicBoost, Ini.MicBoost, IMicBoost);
+ end;
+
+ AddButton(Theme.OptionsRecord.ButtonExit);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsRecord.onShow;
+begin
+ Interaction := 0;
+ writeln( 'AudioInput.CaptureStart') ;
+
+ PlayersPlay := 2; // TODO : This needs fixing
+ AudioInput.CaptureStart;
+
+end;
+
+procedure TScreenOptionsRecord.onHide;
+begin
+ AudioInput.CaptureStop;
+end;
+
+procedure TScreenOptionsRecord.UpdateCard;
+var
+ SourceIndex: integer;
+ InputDevice: TAudioInputDevice;
+ InputDeviceCfg: PInputDeviceConfig;
+begin
+ Log.LogStatus('Update input-device', 'TScreenOptionsRecord.UpdateCard') ;
+
+ AudioInput.CaptureStop;
+
+ if (Card > High(AudioInputProcessor.Device)) then
+ Card := 0;
+
+ if (Length(AudioInputProcessor.Device) > 0) then
+ begin
+ InputDevice := AudioInputProcessor.Device[Card];
+ InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
+
+ SetLength(IInput, Length(InputDevice.Source));
+ for SourceIndex := 0 to High(InputDevice.Source) do begin
+ IInput[SourceIndex] := InputDevice.Source[SourceIndex].Name;
+ end;
+
+ UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectSlideInput, IInput,
+ InputDeviceCfg^.Input);
+ UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelL, SelectSlideChannelL, IChannel,
+ InputDeviceCfg^.ChannelToPlayerMap[0]);
+ UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelR, SelectSlideChannelR, IChannel,
+ InputDeviceCfg^.ChannelToPlayerMap[1]);
+ end;
+
+ AudioInput.CaptureStart;
+end;
+
+function TScreenOptionsRecord.Draw: boolean;
+begin
+ DrawBG;
+ DrawFG;
+
+ // TODO : this needs to be positioned correctly
+ if PlayersPlay = 1 then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+
+ if PlayersPlay = 2 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
+ end;
+ end;
+
+ if PlayersPlay = 3 then begin
+ SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
+ end;
+ end;
+
+ Result := True;
+end;
+
+
+end.
diff --git a/Game/Code/Screens/UScreenOptionsSound.pas b/Game/Code/Screens/UScreenOptionsSound.pas index 64a0413f..da5c6e90 100644 --- a/Game/Code/Screens/UScreenOptionsSound.pas +++ b/Game/Code/Screens/UScreenOptionsSound.pas @@ -34,14 +34,14 @@ begin SDLK_BACKSPACE :
begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenOptions);
end;
SDLK_RETURN:
begin
if SelInteraction = 6 then begin
Ini.Save;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenOptions);
end;
end;
@@ -52,14 +52,14 @@ begin SDLK_RIGHT:
begin
if (SelInteraction >= 0) and (SelInteraction <= 6) then begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractInc;
end;
end;
SDLK_LEFT:
begin
if (SelInteraction >= 0) and (SelInteraction <= 6) then begin
- AudioPlayback.PlayOption;
+ AudioPlayback.PlaySound(SoundLib.Option);
InteractDec;
end;
end;
diff --git a/Game/Code/Screens/UScreenOptionsThemes.pas b/Game/Code/Screens/UScreenOptionsThemes.pas index 114a5e45..239f98fe 100644 --- a/Game/Code/Screens/UScreenOptionsThemes.pas +++ b/Game/Code/Screens/UScreenOptionsThemes.pas @@ -53,7 +53,7 @@ begin UGraphic.UnLoadScreens(); UGraphic.LoadScreens(); - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenOptions); end; SDLK_RETURN: @@ -67,7 +67,7 @@ begin UGraphic.UnLoadScreens(); UGraphic.LoadScreens(); - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenOptions); end; end; @@ -79,7 +79,7 @@ begin begin if (SelInteraction >= 0) and (SelInteraction <= 2) then begin - AudioPlayback.PlayOption; + AudioPlayback.PlaySound(SoundLib.Option); InteractInc; end; end; @@ -87,7 +87,7 @@ begin begin if (SelInteraction >= 0) and (SelInteraction <= 2) then begin - AudioPlayback.PlayOption; + AudioPlayback.PlaySound(SoundLib.Option); InteractDec; end; end; diff --git a/Game/Code/Screens/UScreenPartyNewRound.pas b/Game/Code/Screens/UScreenPartyNewRound.pas index 2f07dcb0..198708cc 100644 --- a/Game/Code/Screens/UScreenPartyNewRound.pas +++ b/Game/Code/Screens/UScreenPartyNewRound.pas @@ -101,13 +101,13 @@ begin SDLK_ESCAPE, SDLK_BACKSPACE : begin - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); CheckFadeTo(@ScreenMain,'MSG_END_PARTY'); end; SDLK_RETURN: begin - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); if DLLMan.Selected.LoadSong then begin //Select PartyMode ScreenSong diff --git a/Game/Code/Screens/UScreenPartyOptions.pas b/Game/Code/Screens/UScreenPartyOptions.pas index c8cb2bb5..1b5cf976 100644 --- a/Game/Code/Screens/UScreenPartyOptions.pas +++ b/Game/Code/Screens/UScreenPartyOptions.pas @@ -66,7 +66,7 @@ begin SDLK_ESCAPE, SDLK_BACKSPACE : begin - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenMain); end; @@ -125,7 +125,7 @@ begin // to-do : Party //PartySession.StartNewParty(Rounds + 2); - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); //Go to Player Screen FadeTo(@ScreenPartyPlayer); end; @@ -137,7 +137,7 @@ begin SDLK_UP: InteractPrev; SDLK_RIGHT: begin - AudioPlayback.PlayOption; + AudioPlayback.PlaySound(SoundLib.Option); InteractInc; //Change Playlist2 if Playlist is Changed @@ -152,7 +152,7 @@ begin end; SDLK_LEFT: begin - AudioPlayback.PlayOption; + AudioPlayback.PlaySound(SoundLib.Option); InteractDec; //Change Playlist2 if Playlist is Changed diff --git a/Game/Code/Screens/UScreenPartyPlayer.pas b/Game/Code/Screens/UScreenPartyPlayer.pas index 3bd33a5c..68f76952 100644 --- a/Game/Code/Screens/UScreenPartyPlayer.pas +++ b/Game/Code/Screens/UScreenPartyPlayer.pas @@ -186,7 +186,7 @@ begin SDLK_ESCAPE:
begin
Ini.SaveNames;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenPartyOptions);
end;
diff --git a/Game/Code/Screens/UScreenPartyScore.pas b/Game/Code/Screens/UScreenPartyScore.pas index 6215e65a..6b21323b 100644 --- a/Game/Code/Screens/UScreenPartyScore.pas +++ b/Game/Code/Screens/UScreenPartyScore.pas @@ -59,7 +59,7 @@ begin SDLK_ESCAPE,
SDLK_BACKSPACE :
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
{if (PartySession.CurRound < High(PartySession.Rounds)) then
FadeTo(@ScreenPartyNewRound)
else // to-do : Party
@@ -71,7 +71,7 @@ begin SDLK_RETURN:
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
// to-do : Party
{if (PartySession.CurRound < High(PartySession.Rounds)) then
FadeTo(@ScreenPartyNewRound)
diff --git a/Game/Code/Screens/UScreenPartyWin.pas b/Game/Code/Screens/UScreenPartyWin.pas index d8a3bd71..5960db06 100644 --- a/Game/Code/Screens/UScreenPartyWin.pas +++ b/Game/Code/Screens/UScreenPartyWin.pas @@ -52,13 +52,13 @@ begin SDLK_ESCAPE,
SDLK_BACKSPACE :
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenMain);
end;
SDLK_RETURN:
begin
- AudioPlayback.PlayStart;
+ AudioPlayback.PlaySound(SoundLib.Start);
FadeTo(@ScreenMain);
end;
end;
diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas index 5216477d..6a5b4e90 100644 --- a/Game/Code/Screens/UScreenSing.pas +++ b/Game/Code/Screens/UScreenSing.pas @@ -153,7 +153,7 @@ begin //Sound[0].BufferLong Finish; - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenScore); end; diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas index 7d2eba07..ed827ec8 100644 --- a/Game/Code/Screens/UScreenSingModi.pas +++ b/Game/Code/Screens/UScreenSingModi.pas @@ -75,6 +75,16 @@ type //procedure Pause; //Pause Mod(Toggles Pause) end; +type + TCustomSoundEntry = record
+ Filename : String;
+ Stream : TAudioPlaybackStream;
+ end;
+
+var + //Custom Sounds + CustomSounds: array of TCustomSoundEntry; + //Procedured for Plugin function LoadTex (const Name, Typ: PChar): TsmallTexture; stdcall; //function Translate (const Name: PChar): PChar; stdcall; @@ -101,7 +111,7 @@ begin SDLK_BACKSPACE : begin Finish; - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenPartyScore); end; @@ -656,14 +666,34 @@ begin end; function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound +var + S: TAudioPlaybackStream; + I: Integer; + F: String; begin - Result := AudioPlayback.LoadCustomSound(String(Name)); + //Search for Sound in already loaded Sounds + F := UpperCase(SoundPath + FileName); + For I := 0 to High(CustomSounds) do + begin + if (UpperCase(CustomSounds[I].Filename) = F) then + begin + Result := I; + Exit; + end; + end; + + S := AudioPlayback.OpenSound(SoundPath + String(Name)); + if (S <> nil) then + Result := High(CustomSounds) + else + Result := 0; end; procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound begin - AudioPlayback.PlayCustomSound(Index); + if (Index <= High(CustomSounds)) then + AudioPlayback.PlaySound(CustomSounds[Index].Stream); end; end. ->>>>>>> .r429 + diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas index 4773cdac..3be0be84 100644 --- a/Game/Code/Screens/UScreenSong.pas +++ b/Game/Code/Screens/UScreenSong.pas @@ -29,6 +29,11 @@ uses type TScreenSong = class(TMenu) + private + EqualizerData: TFFTData; // moved here to avoid stack overflows + EqualizerBands: array of Byte; + EqualizerTime: Cardinal; + EqualizerTime2: Byte; public TextArtist: integer; TextTitle: integer; @@ -52,10 +57,6 @@ type is_jump: boolean; // Jump to Song Mod is_jump_title:boolean; //Jump to SOng MOd-YTrue if search for Title - EqualizerBands: array of Byte; - EqualizerTime: Cardinal; - EqualizerTime2: Byte; - //Party Mod Mode: TSingMode; @@ -270,7 +271,7 @@ begin begin SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2)); - AudioPlayback.PlayChange; + AudioPlayback.PlaySound(SoundLib.Change); ChangeMusic; SetScroll4; @@ -291,7 +292,7 @@ begin begin SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2)); - AudioPlayback.PlayChange; + AudioPlayback.PlaySound(SoundLib.Change); ChangeMusic; SetScroll4; @@ -369,7 +370,7 @@ begin else begin AudioPlayback.Stop; - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenMain); end; @@ -379,7 +380,7 @@ begin //When in party Mode then Ask before Close else if (Mode = smPartyMode) then begin - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); CheckFadeTo(@ScreenMain,'MSG_END_PARTY'); end; end; @@ -504,7 +505,7 @@ begin FixSelected; //Play Music: - AudioPlayback.PlayChange; + AudioPlayback.PlaySound(SoundLib.Change); ChangeMusic; end; @@ -547,7 +548,7 @@ begin FixSelected; //Play Music: - AudioPlayback.PlayChange; + AudioPlayback.PlaySound(SoundLib.Change); ChangeMusic; end; end; @@ -559,7 +560,7 @@ begin begin if (Songs.SongList.Count > 0) AND (Mode = smNormal) then begin - AudioPlayback.PlayChange; + AudioPlayback.PlaySound(SoundLib.Change); SelectNext; // InteractNext; // SongTarget := Interaction; @@ -573,7 +574,7 @@ begin SDLK_LEFT: begin if (Songs.SongList.Count > 0)AND (Mode = smNormal) then begin - AudioPlayback.PlayChange; + AudioPlayback.PlaySound(SoundLib.Change); SelectPrev; ChangeMusic; SetScroll4; @@ -655,7 +656,7 @@ begin begin SkipTo(Random(CatSongs.VisibleSongs)); end; - AudioPlayback.PlayChange; + AudioPlayback.PlaySound(SoundLib.Change); ChangeMusic; SetScroll4; @@ -1804,7 +1805,6 @@ end; procedure TScreenSong.DrawEqualizer; var - Data: TFFTData; //Audio Data I, J: Integer; Res: byte; A, B: Integer; @@ -1822,7 +1822,7 @@ begin if (A <> EqualizerTime) then begin EqualizerTime := A; - Data := AudioPlayback.GetFFTData; + AudioPlayback.GetFFTData(EqualizerData); B := 0; Pos := 0; @@ -1850,23 +1850,23 @@ begin end; if I > 35 then - Data[i] := Data[i] * 8 + EqualizerData[i] := EqualizerData[i] * 8 else if I > 11 then - Data[i] := Data[i] * 4.5 + EqualizerData[i] := EqualizerData[i] * 4.5 else - Data[i] := Data[i] * 1.1; + EqualizerData[i] := EqualizerData[i] * 1.1; - if (Data[i] >= 1) then - Data[i] := 0.9999999999999; + if (EqualizerData[i] >= 1) then + EqualizerData[i] := 0.9999999999999; try if ( assigned( Theme ) ) AND ( assigned( Theme.Song ) ) AND - ( i < length( Data ) ) THEN + ( i < length( EqualizerData ) ) THEN begin - if single( Data[i] ) > 1 then + if single( EqualizerData[i] ) > 1 then begin - lTmp := Single(Data[i]) * Theme.Song.Equalizer.Length; + lTmp := Single(EqualizerData[i]) * Theme.Song.Equalizer.Length; if lTmp > Pos then Pos := lTmp; end; @@ -1874,7 +1874,7 @@ begin except {$IFDEF FPC} on E:EInvalidOp do - writeln( 'UScreenSong - DOH !!!! ('+inttostr(i)+' '+ inttostr( integer( Data[i] ) )+' * '+ ')' ); + writeln( 'UScreenSong - DOH !!!! ('+inttostr(i)+' '+ inttostr( integer( EqualizerData[i] ) )+' * '+ ')' ); {$ENDIF} end @@ -1989,7 +1989,7 @@ begin end; end; - AudioPlayback.PlayChange; + AudioPlayback.PlaySound(SoundLib.Change); ChangeMusic; SetScroll; UpdateLCD; @@ -2129,7 +2129,7 @@ begin if (Songs.SongList.Count > 0) and (not CatSongs.Song[Interaction].Main) AND (Mode = smNormal) then begin AudioPlayback.Stop; - AudioPlayback.PlayStart; + AudioPlayback.PlaySound(SoundLib.Start); ScreenEditSub.Path := CatSongs.Song[Interaction].Path; ScreenEditSub.FileName := CatSongs.Song[Interaction].FileName; FadeTo(@ScreenEditSub); diff --git a/Game/Code/Screens/UScreenSongJumpto.pas b/Game/Code/Screens/UScreenSongJumpto.pas index 14228964..dfa90009 100644 --- a/Game/Code/Screens/UScreenSongJumpto.pas +++ b/Game/Code/Screens/UScreenSongJumpto.pas @@ -67,7 +67,7 @@ begin SDLK_ESCAPE:
begin
Visible := False;
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
if (VisSongs = 0) AND (Length(Button[0].Text[0].Text) > 0) then
begin
ScreenSong.UnLoadDetailedCover;
diff --git a/Game/Code/Screens/UScreenSongMenu.pas b/Game/Code/Screens/UScreenSongMenu.pas index 88b0de32..ae0bc9ba 100644 --- a/Game/Code/Screens/UScreenSongMenu.pas +++ b/Game/Code/Screens/UScreenSongMenu.pas @@ -96,7 +96,7 @@ begin SDLK_ESCAPE, SDLK_BACKSPACE : begin - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); Visible := False; end; diff --git a/Game/Code/Screens/UScreenStatDetail.pas b/Game/Code/Screens/UScreenStatDetail.pas index 414055f9..d793baf0 100644 --- a/Game/Code/Screens/UScreenStatDetail.pas +++ b/Game/Code/Screens/UScreenStatDetail.pas @@ -53,7 +53,7 @@ begin SDLK_ESCAPE,
SDLK_BACKSPACE :
begin
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenStatMain);
end;
SDLK_RETURN:
@@ -76,7 +76,7 @@ begin end;
if Interaction = 3 then begin
- AudioPlayback.PlayBack;
+ AudioPlayback.PlaySound(SoundLib.Back);
FadeTo(@ScreenStatMain);
end;
end;
diff --git a/Game/Code/Screens/UScreenStatMain.pas b/Game/Code/Screens/UScreenStatMain.pas index f7257201..53154d6e 100644 --- a/Game/Code/Screens/UScreenStatMain.pas +++ b/Game/Code/Screens/UScreenStatMain.pas @@ -62,7 +62,7 @@ begin SDLK_BACKSPACE : begin Ini.Save; - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenMain); end; SDLK_RETURN: @@ -70,12 +70,12 @@ begin //Exit Button Pressed if Interaction = 4 then begin - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenMain); end else //One of the Stats Buttons Pressed begin - AudioPlayback.PlayBack; + AudioPlayback.PlaySound(SoundLib.Back); ScreenStatDetail.Typ := Interaction; FadeTo(@ScreenStatDetail); end; |