From 7968b0878c1c13f61dddbacb603e00997af38f63 Mon Sep 17 00:00:00 2001 From: eddie-0815 Date: Tue, 25 Mar 2008 20:41:08 +0000 Subject: Fixed compilation on the mac. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@972 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UAudioInput_Bass.pas | 542 ++--- Game/Code/Classes/UCommon.pas | 574 ++--- Game/Code/Classes/UConfig.pas | 2 +- Game/Code/Classes/UMain.pas | 2329 ++++++++++---------- .../MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 | 346 ++- .../MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser | 356 ++- .../MacOSX/UltraStarDX.xcodeproj/project.pbxproj | 4 +- Game/Code/MacOSX/Wrapper/OpenGL12.pas | 1 + Game/Code/Menu/UMenu.pas | 11 + Game/Code/Screens/UScreenEdit.pas | 4 +- Game/Code/Screens/UScreenEditConvert.pas | 12 +- Game/Code/Screens/UScreenEditHeader.pas | 4 +- Game/Code/Screens/UScreenEditSub.pas | 22 +- Game/Code/Screens/UScreenLevel.pas | 16 +- Game/Code/Screens/UScreenMain.pas | 5 +- Game/Code/Screens/UScreenOptions.pas | 16 +- Game/Code/Screens/UScreenOptionsAdvanced.pas | 16 +- Game/Code/Screens/UScreenOptionsGame.pas | 16 +- Game/Code/Screens/UScreenOptionsGraphics.pas | 4 +- Game/Code/Screens/UScreenOptionsLyrics.pas | 4 +- Game/Code/Screens/UScreenOptionsRecord.pas | 4 +- Game/Code/Screens/UScreenOptionsSound.pas | 16 +- Game/Code/Screens/UScreenOptionsThemes.pas | 16 +- Game/Code/Screens/UScreenPartyNewRound.pas | 12 +- Game/Code/Screens/UScreenPartyOptions.pas | 26 +- Game/Code/Screens/UScreenPartyScore.pas | 8 +- Game/Code/Screens/UScreenPartyWin.pas | 12 +- Game/Code/Screens/UScreenPopup.pas | 8 +- Game/Code/Screens/UScreenScore.pas | 8 +- Game/Code/Screens/UScreenSing.pas | 10 +- Game/Code/Screens/UScreenSong.pas | 8 +- Game/Code/Screens/UScreenSongMenu.pas | 16 +- Game/Code/Screens/UScreenStatDetail.pas | 4 +- Game/Code/Screens/UScreenStatMain.pas | 16 +- Game/Code/Screens/UScreenTop5.pas | 16 +- Game/Code/switches.inc | 268 +-- 36 files changed, 2619 insertions(+), 2113 deletions(-) (limited to 'Game/Code') diff --git a/Game/Code/Classes/UAudioInput_Bass.pas b/Game/Code/Classes/UAudioInput_Bass.pas index bf0c916e..adc3bf3e 100644 --- a/Game/Code/Classes/UAudioInput_Bass.pas +++ b/Game/Code/Classes/UAudioInput_Bass.pas @@ -1,267 +1,275 @@ -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; - - function Init(): boolean; - function Start(): boolean; 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 } - -function TBassInputDevice.Init(): boolean; -begin - Result := false; - - // 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; - - Result := true; -end; - -{* - * Start input-capturing on this device. - * TODO: call BASS_RecordInit only once - *} -function TBassInputDevice.Start(): boolean; -var - flags: Word; -const - latency = 20; // 20ms callback period (= latency) -begin - Result := false; - - // recording already started -> stop first - if (RecordStream <> 0) then - Stop(); - - if not Init() then - Exit; - - case AudioFormat.Format of - asfS16: flags := 0; - asfFloat: flags := BASS_SAMPLE_FLOAT; - asfU8: flags := BASS_SAMPLE_8BITS; - else begin - Log.LogError('Unhandled sample-format', 'TBassInputDevice.Start'); - Exit; - end; - end; - - // start capturing - RecordStream := BASS_RecordStart(AudioFormat.SampleRate, AudioFormat.Channels, - MakeLong(flags, latency), - @MicrophoneCallback, DeviceIndex); - if (RecordStream = 0) then - begin - BASS_RecordFree; - Exit; - end; - - Result := true; -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; - RecordInfo: BASS_RECORDINFO; -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; - - // try to intialize the device - if not BASS_RecordInit(BassDeviceID) then - begin - Log.LogStatus('Failed to initialize BASS Capture-Device['+inttostr(BassDeviceID)+']', - 'TAudioInput_Bass.InitializeRecord'); - end - else - begin - 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); - - // retrieve recording device info - BASS_RecordGetInfo(RecordInfo); - - // FIXME: does BASS use LSB/MSB or system integer values for 16bit? - - // check if BASS has capture-freq. info - if (RecordInfo.freq > 0) then - begin - // use current input sample rate (available only on Windows Vista and OSX). - // Recording at this rate will give the best quality and performance, as no resampling is required. - BassDevice.AudioFormat := TAudioFormatInfo.Create(2, RecordInfo.freq, asfS16) - end - else - begin - // BASS does not provide an explizit input channel count (except BASS_RECORDINFO.formats) - // but it doesn't fail if we use stereo input on a mono device - // -> use stereo by default - BassDevice.AudioFormat := TAudioFormatInfo.Create(2, 44100, asfS16) - end; - - SetLength(BassDevice.CaptureChannel, BassDevice.AudioFormat.Channels); - - // get input sources - SourceIndex := 0; - BassDevice.MicSource := 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 <> -1) and ((Flags and BASS_INPUT_TYPE_MIC) <> 0)) then - begin - BassDevice.MicSource := SourceIndex; - end; - - Inc(SourceIndex); - end; - - //Writeln('BASS_RecordFree'); - // FIXME: this call hangs in FPC (windows) every 2nd time USDX is called. - // Maybe because the sound-device was not released properly? - BASS_RecordFree; - //Writeln('BASS_RecordFree - Done'); - - Inc(DeviceIndex); - end; - - 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. +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; + + function Init(): boolean; + function Start(): boolean; 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 } + +function TBassInputDevice.Init(): boolean; +begin + Result := false; + + // 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; + + Result := true; +end; + +{* + * Start input-capturing on this device. + * TODO: call BASS_RecordInit only once + *} +function TBassInputDevice.Start(): boolean; +var + flags: Word; +const + latency = 20; // 20ms callback period (= latency) +begin + Result := false; + + // recording already started -> stop first + if (RecordStream <> 0) then + Stop(); + + if not Init() then + Exit; + + case AudioFormat.Format of + asfS16: flags := 0; + asfFloat: flags := BASS_SAMPLE_FLOAT; + asfU8: flags := BASS_SAMPLE_8BITS; + else begin + Log.LogError('Unhandled sample-format', 'TBassInputDevice.Start'); + Exit; + end; + end; + + // start capturing + RecordStream := BASS_RecordStart(AudioFormat.SampleRate, AudioFormat.Channels, + MakeLong(flags, latency), + @MicrophoneCallback, DeviceIndex); + if (RecordStream = 0) then + begin + BASS_RecordFree; + Exit; + end; + + Result := true; +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; + RecordInfo: BASS_RECORDINFO; +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; + + // try to intialize the device + if not BASS_RecordInit(BassDeviceID) then + begin + Log.LogStatus('Failed to initialize BASS Capture-Device['+inttostr(BassDeviceID)+']', + 'TAudioInput_Bass.InitializeRecord'); + end + else + begin + 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); + + // retrieve recording device info + BASS_RecordGetInfo(RecordInfo); + + // FIXME: does BASS use LSB/MSB or system integer values for 16bit? + + // check if BASS has capture-freq. info + if (RecordInfo.freq > 0) then + begin + // use current input sample rate (available only on Windows Vista and OSX). + // Recording at this rate will give the best quality and performance, as no resampling is required. + BassDevice.AudioFormat := TAudioFormatInfo.Create(2, RecordInfo.freq, asfS16) + end + else + begin + // BASS does not provide an explizit input channel count (except BASS_RECORDINFO.formats) + // but it doesn't fail if we use stereo input on a mono device + // -> use stereo by default + BassDevice.AudioFormat := TAudioFormatInfo.Create(2, 44100, asfS16) + end; + + SetLength(BassDevice.CaptureChannel, BassDevice.AudioFormat.Channels); + + // get input sources + SourceIndex := 0; + BassDevice.MicSource := 0; + + // process each input + while true do + begin + SourceName := BASS_RecordGetInputName(SourceIndex); + {$IFDEF DARWIN} + // Patch for SingStar USB-Microphones: + if ((SourceName = nil) and (SourceIndex = 0) and (Pos('Serial#', Descr) > 0)) then + SourceName := 'Microphone' + else + break; + {$ELSE} + if (SourceName = nil) then + break; + {$ENDIF} + + SetLength(BassDevice.Source, SourceIndex+1); + BassDevice.Source[SourceIndex].Name := + UnifyDeviceSourceName(SourceName, BassDevice.Description); + + // set mic index + Flags := BASS_RecordGetInput(SourceIndex); + if ((Flags <> -1) and ((Flags and BASS_INPUT_TYPE_MIC) <> 0)) then + begin + BassDevice.MicSource := SourceIndex; + end; + + Inc(SourceIndex); + end; + + //Writeln('BASS_RecordFree'); + // FIXME: this call hangs in FPC (windows) every 2nd time USDX is called. + // Maybe because the sound-device was not released properly? + BASS_RecordFree; + //Writeln('BASS_RecordFree - Done'); + + Inc(DeviceIndex); + end; + + 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/UCommon.pas b/Game/Code/Classes/UCommon.pas index c5dde0c8..62d7df65 100644 --- a/Game/Code/Classes/UCommon.pas +++ b/Game/Code/Classes/UCommon.pas @@ -1,281 +1,293 @@ -unit UCommon; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -uses - SysUtils, -{$IFDEF LAZARUS} - lResources, -{$ENDIF} - ULog, -{$IFDEF DARWIN} - messages, -{$ENDIF} -{$IFDEF win32} - windows; -{$ELSE} - lcltype, - messages; -{$ENDIF} - -{$IFNDEF win32} -type - hStream = THandle; - HGLRC = THandle; - TLargeInteger = Int64; - TWin32FindData = LongInt; -{$ENDIF} - -{$IFDEF LAZARUS} - function LazFindResource( const aName, aType : String ): TLResource; -{$ENDIF} - -{$IFDEF FPC} - -function RandomRange(aMin: Integer; aMax: Integer) : Integer; - -function MaxValue(const Data: array of Double): Double; -function MinValue(const Data: array of Double): Double; - - {$IFDEF WIN32} - type - TWndMethod = procedure(var Message: TMessage) of object; - function AllocateHWnd(Method: TWndMethod): HWND; - procedure DeallocateHWnd(Wnd: HWND); - {$ENDIF} // Win32 - -{$ENDIF} // FPC Only - -function StringReplaceW(text : WideString; search, rep: WideChar):WideString; -function AdaptFilePaths( const aPath : widestring ): widestring; - - -{$IFNDEF win32} -(* - function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool; - function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool; -*) - procedure ZeroMemory( Destination: Pointer; Length: DWORD ); -{$ENDIF} - -// eddie: FindFirstW etc are now in UPlatformWindows.pas - -(* - * Character classes - *) - -function IsAlphaChar(ch: WideChar): boolean; -function IsNumericChar(ch: WideChar): boolean; -function IsAlphaNumericChar(ch: WideChar): boolean; -function IsPunctuationChar(ch: WideChar): boolean; -function IsControlChar(ch: WideChar): boolean; - - -implementation - -function StringReplaceW(text : WideString; search, rep: WideChar):WideString; -var - iPos : integer; -// sTemp : WideString; -begin -(* - result := text; - iPos := Pos(search, result); - while (iPos > 0) do - begin - sTemp := copy(result, iPos + length(search), length(result)); - result := copy(result, 1, iPos - 1) + rep + sTEmp; - iPos := Pos(search, result); - end; -*) - result := text; - - if search = rep then - exit; - - for iPos := 0 to length( result ) - 1 do - begin - if result[ iPos ] = search then - result[ iPos ] := rep; - end; -end; - -function AdaptFilePaths( const aPath : widestring ): widestring; -begin - result := StringReplaceW( aPath, '\', PathDelim );//, [rfReplaceAll] ); -end; - - -{$IFNDEF win32} -procedure ZeroMemory( Destination: Pointer; Length: DWORD ); -begin - FillChar( Destination^, Length, 0 ); -end; //ZeroMemory - -(* -function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool; - - // From http://en.wikipedia.org/wiki/RDTSC - function RDTSC: Int64; register; - asm - rdtsc - end; - -begin - // Use clock_gettime here maybe ... from libc - lpPerformanceCount := RDTSC(); - result := true; -end; - -function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool; -begin - lpFrequency := 0; - result := true; -end; -*) -{$ENDIF} - - -{$IFDEF LAZARUS} - -function LazFindResource( const aName, aType : String ): TLResource; -var - iCount : Integer; -begin - result := nil; - - for iCount := 0 to LazarusResources.count -1 do - begin - if ( LazarusResources.items[ iCount ].Name = aName ) AND - ( LazarusResources.items[ iCount ].ValueType = aType ) THEN - begin - result := LazarusResources.items[ iCount ]; - exit; - end; - end; -end; -{$ENDIF} - -{$IFDEF FPC} -// FIXME: already exists in FPC -function MaxValue(const Data: array of Double): Double; -var - I: Integer; -begin - Result := Data[Low(Data)]; - for I := Low(Data) + 1 to High(Data) do - if Result < Data[I] then - Result := Data[I]; -end; - -// FIXME: already exists in FPC -function MinValue(const Data: array of Double): Double; -var - I: Integer; -begin - Result := Data[Low(Data)]; - for I := Low(Data) + 1 to High(Data) do - if Result > Data[I] then - Result := Data[I]; -end; - -function RandomRange(aMin: Integer; aMax: Integer) : Integer; -begin -RandomRange := Random(aMax-aMin) + aMin ; -end; - - -// NOTE !!!!!!!!!! -// AllocateHWnd is in lclintfh.inc - -{$IFDEF MSWINDOWS} -// TODO : JB this is dodgey and bad... find a REAL solution ! -function AllocateHWnd(Method: TWndMethod): HWND; -var - TempClass: TWndClass; - ClassRegistered: Boolean; -begin - Result := CreateWindowEx(WS_EX_TOOLWINDOW, '', '', WS_POPUP , 0, 0, 0, 0, 0, 0, HInstance, nil); -end; - -procedure DeallocateHWnd(Wnd: HWND); -var - Instance: Pointer; -begin - Instance := Pointer(GetWindowLong(Wnd, GWL_WNDPROC)); - DestroyWindow(Wnd); -end; -{$ENDIF} -{$IFDEF DARWIN} -// TODO : Situation for the mac isn't better ! -function AllocateHWnd(Method: TWndMethod): HWND; -begin -end; - -procedure DeallocateHWnd(Wnd: HWND); -begin -end; -{$ENDIF} // IFDEF DARWIN - -{$ENDIF} // IFDEF FPC - -function IsAlphaChar(ch: WideChar): boolean; -begin - // TODO: add chars > 255 when unicode-fonts work? - case ch of - 'A'..'Z', // A-Z - 'a'..'z', // a-z - #170,#181,#186, - #192..#214, - #216..#246, - #248..#255: - Result := true; - else - Result := false; - end; -end; - -function IsNumericChar(ch: WideChar): boolean; -begin - case ch of - '0'..'9': - Result := true; - else - Result := false; - end; -end; - -function IsAlphaNumericChar(ch: WideChar): boolean; -begin - Result := (IsAlphaChar(ch) or IsNumericChar(ch)); -end; - -function IsPunctuationChar(ch: WideChar): boolean; -begin - // TODO: add chars outside of Latin1 basic (0..127)? - case ch of - ' '..'/',':'..'@','['..'`','{'..'~': - Result := true; - else - Result := false; - end; -end; - -function IsControlChar(ch: WideChar): boolean; -begin - case ch of - #0..#31, - #127..#159: - Result := true; - else - Result := false; - end; -end; - -end. +unit UCommon; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + SysUtils, +{$IFDEF LAZARUS} + lResources, +{$ENDIF} + ULog, +{$IFDEF DARWIN} + messages, +{$ENDIF} +{$IFDEF win32} + windows; +{$ELSE} + lcltype, + messages; +{$ENDIF} + +{$IFNDEF win32} +type + hStream = THandle; + HGLRC = THandle; + TLargeInteger = Int64; + TWin32FindData = LongInt; +{$ENDIF} + +{$IFDEF LAZARUS} + function LazFindResource( const aName, aType : String ): TLResource; +{$ENDIF} + +{$IFDEF DARWIN} + procedure ShowMessage( const msg : String ); +{$ENDIF} + +{$IFDEF FPC} + +function RandomRange(aMin: Integer; aMax: Integer) : Integer; + +function MaxValue(const Data: array of Double): Double; +function MinValue(const Data: array of Double): Double; + + {$IFDEF WIN32} + type + TWndMethod = procedure(var Message: TMessage) of object; + function AllocateHWnd(Method: TWndMethod): HWND; + procedure DeallocateHWnd(Wnd: HWND); + {$ENDIF} // Win32 + +{$ENDIF} // FPC Only + +function StringReplaceW(text : WideString; search, rep: WideChar):WideString; +function AdaptFilePaths( const aPath : widestring ): widestring; + + +{$IFNDEF win32} +(* + function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool; + function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool; +*) + procedure ZeroMemory( Destination: Pointer; Length: DWORD ); +{$ENDIF} + +// eddie: FindFirstW etc are now in UPlatformWindows.pas + +(* + * Character classes + *) + +function IsAlphaChar(ch: WideChar): boolean; +function IsNumericChar(ch: WideChar): boolean; +function IsAlphaNumericChar(ch: WideChar): boolean; +function IsPunctuationChar(ch: WideChar): boolean; +function IsControlChar(ch: WideChar): boolean; + + +implementation + +function StringReplaceW(text : WideString; search, rep: WideChar):WideString; +var + iPos : integer; +// sTemp : WideString; +begin +(* + result := text; + iPos := Pos(search, result); + while (iPos > 0) do + begin + sTemp := copy(result, iPos + length(search), length(result)); + result := copy(result, 1, iPos - 1) + rep + sTEmp; + iPos := Pos(search, result); + end; +*) + result := text; + + if search = rep then + exit; + + for iPos := 0 to length( result ) - 1 do + begin + if result[ iPos ] = search then + result[ iPos ] := rep; + end; +end; + +function AdaptFilePaths( const aPath : widestring ): widestring; +begin + result := StringReplaceW( aPath, '\', PathDelim );//, [rfReplaceAll] ); +end; + + +{$IFNDEF win32} +procedure ZeroMemory( Destination: Pointer; Length: DWORD ); +begin + FillChar( Destination^, Length, 0 ); +end; //ZeroMemory + +(* +function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool; + + // From http://en.wikipedia.org/wiki/RDTSC + function RDTSC: Int64; register; + asm + rdtsc + end; + +begin + // Use clock_gettime here maybe ... from libc + lpPerformanceCount := RDTSC(); + result := true; +end; + +function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool; +begin + lpFrequency := 0; + result := true; +end; +*) +{$ENDIF} + + +{$IFDEF LAZARUS} + +function LazFindResource( const aName, aType : String ): TLResource; +var + iCount : Integer; +begin + result := nil; + + for iCount := 0 to LazarusResources.count -1 do + begin + if ( LazarusResources.items[ iCount ].Name = aName ) AND + ( LazarusResources.items[ iCount ].ValueType = aType ) THEN + begin + result := LazarusResources.items[ iCount ]; + exit; + end; + end; +end; +{$ENDIF} + +{$IFDEF FPC} +// FIXME: already exists in FPC +function MaxValue(const Data: array of Double): Double; +var + I: Integer; +begin + Result := Data[Low(Data)]; + for I := Low(Data) + 1 to High(Data) do + if Result < Data[I] then + Result := Data[I]; +end; + +// FIXME: already exists in FPC +function MinValue(const Data: array of Double): Double; +var + I: Integer; +begin + Result := Data[Low(Data)]; + for I := Low(Data) + 1 to High(Data) do + if Result > Data[I] then + Result := Data[I]; +end; + +function RandomRange(aMin: Integer; aMax: Integer) : Integer; +begin +RandomRange := Random(aMax-aMin) + aMin ; +end; + + +// NOTE !!!!!!!!!! +// AllocateHWnd is in lclintfh.inc + +{$IFDEF MSWINDOWS} +// TODO : JB this is dodgey and bad... find a REAL solution ! +function AllocateHWnd(Method: TWndMethod): HWND; +var + TempClass: TWndClass; + ClassRegistered: Boolean; +begin + Result := CreateWindowEx(WS_EX_TOOLWINDOW, '', '', WS_POPUP , 0, 0, 0, 0, 0, 0, HInstance, nil); +end; + +procedure DeallocateHWnd(Wnd: HWND); +var + Instance: Pointer; +begin + Instance := Pointer(GetWindowLong(Wnd, GWL_WNDPROC)); + DestroyWindow(Wnd); +end; +{$ENDIF} +{$IFDEF DARWIN} +// TODO : Situation for the mac isn't better ! +function AllocateHWnd(Method: TWndMethod): HWND; +begin +end; + +procedure DeallocateHWnd(Wnd: HWND); +begin +end; +{$ENDIF} // IFDEF DARWIN + +{$ENDIF} // IFDEF FPC + +{$IFDEF DARWIN} +procedure ShowMessage( const msg : String ); +begin + //eddie: what to do here? +end; +{$ENDIF} + + +function IsAlphaChar(ch: WideChar): boolean; +begin + // TODO: add chars > 255 when unicode-fonts work? + case ch of + 'A'..'Z', // A-Z + 'a'..'z', // a-z + #170,#181,#186, + #192..#214, + #216..#246, + #248..#255: + Result := true; + else + Result := false; + end; +end; + +function IsNumericChar(ch: WideChar): boolean; +begin + case ch of + '0'..'9': + Result := true; + else + Result := false; + end; +end; + +function IsAlphaNumericChar(ch: WideChar): boolean; +begin + Result := (IsAlphaChar(ch) or IsNumericChar(ch)); +end; + +function IsPunctuationChar(ch: WideChar): boolean; +begin + // TODO: add chars outside of Latin1 basic (0..127)? + case ch of + ' '..'/',':'..'@','['..'`','{'..'~': + Result := true; + else + Result := false; + end; +end; + +function IsControlChar(ch: WideChar): boolean; +begin + case ch of + #0..#31, + #127..#159: + Result := true; + else + Result := false; + end; +end; + +end. diff --git a/Game/Code/Classes/UConfig.pas b/Game/Code/Classes/UConfig.pas index ee4685d3..ae9ac150 100644 --- a/Game/Code/Classes/UConfig.pas +++ b/Game/Code/Classes/UConfig.pas @@ -196,7 +196,7 @@ function USDXShortVersionStr(): string; implementation uses - StrUtils; + StrUtils, Math; function USDXShortVersionStr(): string; begin diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index 879c5c79..f9762c1e 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -1,1165 +1,1164 @@ -unit UMain; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -uses - SDL, - UGraphic, - UMusic, - URecord, - UTime, - SysUtils, - UDisplay, - UIni, - ULog, - ULyrics, - UScreenSing, - USong, - OpenGL12, - {$IFDEF UseSerialPort} - //zlportio, //you can disable it and all PortWriteB calls - {$ENDIF} - //ULCD, //TODO: maybe LCD Support as Plugin? - //ULight, //TODO: maybe Light Support as Plugin? - UThemes; - -type - TPlayer = record - Name: string; - - // Index in Teaminfo record - TeamID: Byte; - PlayerID: Byte; - - // Scores - Score: real; - ScoreLine: real; - ScoreGolden: real; - - ScoreI: integer; - ScoreLineI: integer; - ScoreGoldenI: integer; - ScoreTotalI: integer; - - // LineBonus Mod - ScoreLast: Real;//Last Line Score - - // PerfectLineTwinkle Mod (effect) - LastSentencePerfect: Boolean; - - //Meter: real; - - HighNote: integer; - IlNut: integer; - Note: array of record - Start: integer; - Length: integer; - Detekt: real; // accurate place, detected in the note - Tone: real; - Perfect: boolean; // true if the note matches the original one, lit the star - - // Half size Notes Patch - Hit: boolean; // true if the note Hits the Line - end; - end; - - -var - // Absolute Paths - GamePath: string; - SoundPath: string; - SongPath: string; - LogPath: string; - ThemePath: string; - SkinsPath: string; - ScreenshotsPath: string; - CoversPath: string; - LanguagesPath: string; - PluginPath: string; - VisualsPath: string; - PlayListPath: string; - - UserSongPath: string = ''; - UserCoversPath: string = ''; - UserPlaylistPath: string = ''; - - OGL: Boolean; - Done: Boolean; - Event: TSDL_event; - FileName: string; - Restart: boolean; - - // player and music info - Player: array of TPlayer; - PlayersPlay: integer; - - CurrentSong : TSong; - -procedure InitializePaths; - -Procedure Main; -procedure MainLoop; -procedure CheckEvents; -procedure Sing(Sender: TScreenSing); -procedure NewSentence(Sender: TScreenSing); -procedure NewBeat(Sender: TScreenSing); // executed when on then new beat -procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click -procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection -//procedure NewHalf; // executed when in the half between beats -procedure NewNote(Sender: TScreenSing); // detect note -function GetMidBeat(Time: real): real; -function GetTimeFromBeat(Beat: integer): real; -procedure ClearScores(PlayerNum: integer); - -implementation - -uses - USongs, - UJoystick, - math, - UCommandLine, - ULanguage, - SDL_ttf, - USkins, - UCovers, - UCatCovers, - UDataBase, - UPlaylist, - UDLLManager, - UParty, - UConfig, - UCore, - UGraphicClasses, - UPluginDefs, - UPlatform; - -procedure Main; -var - WndTitle: string; -begin - try - WndTitle := USDXVersionStr; - - if Platform.TerminateIfAlreadyRunning( {var} WndTitle) then - Exit; - - //------------------------------ - //StartUp - Create Classes and Load Files - //------------------------------ - USTime := TTime.Create; - - // Commandline Parameter Parser - Params := TCMDParams.Create; - - // Log + Benchmark - Log := TLog.Create; - Log.Title := WndTitle; - Log.Enabled := not Params.NoLog; - Log.BenchmarkStart(0); - - // Language - Log.BenchmarkStart(1); - Log.LogStatus('Initialize Paths', 'Initialization'); - InitializePaths; - Log.LogStatus('Load Language', 'Initialization'); - Language := TLanguage.Create; - - // Add Const Values: - Language.AddConst('US_VERSION', USDXVersionStr); - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Language', 1); - - // SDL - Log.BenchmarkStart(1); - Log.LogStatus('Initialize SDL', 'Initialization'); - SDL_Init(SDL_INIT_VIDEO); - Log.BenchmarkEnd(1); - Log.LogBenchmark('Initializing SDL', 1); - - // SDL_ttf - Log.BenchmarkStart(1); - Log.LogStatus('Initialize SDL_ttf', 'Initialization'); - TTF_Init(); - Log.BenchmarkEnd(1); - Log.LogBenchmark('Initializing SDL_ttf', 1); - - // Skin - Log.BenchmarkStart(1); - Log.LogStatus('Loading Skin List', 'Initialization'); - Skin := TSkin.Create; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Skin List', 1); - - // Ini + Paths - Log.BenchmarkStart(1); - Log.LogStatus('Load Ini', 'Initialization'); - Ini := TIni.Create; - Ini.Load; - - //Load Languagefile - if (Params.Language <> -1) then - Language.ChangeLanguage(ILanguage[Params.Language]) - else - Language.ChangeLanguage(ILanguage[Ini.Language]); - - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Ini', 1); - - // Sound - Log.BenchmarkStart(1); - Log.LogStatus('Initialize Sound', 'Initialization'); - InitializeSound(); - Log.BenchmarkEnd(1); - Log.LogBenchmark('Initializing Sound', 1); - - // Load Sound Settings from Ini - Log.BenchmarkStart(1); - Log.LogStatus('Load Sound Settings', 'Initialization'); - Ini.LoadSoundSettings; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Load Sound Settings', 1); - - // LCD //TODO: maybe LCD Support as Plugin? - //Log.BenchmarkStart(1); - //Log.LogStatus('Load LCD', 'Initialization'); - //LCD := TLCD.Create; - (* - if Ini.LPT = 1 then - begin - //LCD.HalfInterface := true; - LCD.Enable; - LCD.Clear; - LCD.WriteText(1, ' UltraStar '); - LCD.WriteText(2, ' Loading... '); - end; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading LCD', 1); - *) - // Light //TODO: maybe Light Support as Plugin? - (* - Log.BenchmarkStart(1); - Log.LogStatus('Load Light', 'Initialization'); - Light := TLight.Create; - if Ini.LPT = 2 then - begin - Light.Enable; - end; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Light', 1); - *) - - - // Theme - Log.BenchmarkStart(1); - Log.LogStatus('Load Themes', 'Initialization'); - Theme := TTheme.Create(ThemePath + ITheme[Ini.Theme] + '.ini', Ini.Color); - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Themes', 1); - - // Covers Cache - Log.BenchmarkStart(1); - Log.LogStatus('Creating Covers Cache', 'Initialization'); - Covers := TCovers.Create; - Log.LogBenchmark('Loading Covers Cache Array', 1); - Log.BenchmarkStart(1); - - // Category Covers - Log.BenchmarkStart(1); - Log.LogStatus('Creating Category Covers Array', 'Initialization'); - CatCovers:= TCatCovers.Create; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Category Covers Array', 1); - - // Songs - //Log.BenchmarkStart(1); - Log.LogStatus('Creating Song Array', 'Initialization'); - Songs := TSongs.Create; - //Songs.LoadSongList; - - Log.LogStatus('Creating 2nd Song Array', 'Initialization'); - CatSongs := TCatSongs.Create; - - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Songs', 1); - - // PluginManager - Log.BenchmarkStart(1); - Log.LogStatus('PluginManager', 'Initialization'); - DLLMan := TDLLMan.Create; // Load PluginList - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading PluginManager', 1); - - {// Party Mode Manager - Log.BenchmarkStart(1); - Log.LogStatus('PartySession Manager', 'Initialization'); - PartySession := TPartySession.Create; //Load PartySession - - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading PartySession Manager', 1); } - - // Graphics - Log.BenchmarkStart(1); - Log.LogStatus('Initialize 3D', 'Initialization'); - Initialize3D(WndTitle); - Log.BenchmarkEnd(1); - Log.LogBenchmark('Initializing 3D', 1); - - // Score Saving System - Log.BenchmarkStart(1); - Log.LogStatus('DataBase System', 'Initialization'); - DataBase := TDataBaseSystem.Create; - - if (Params.ScoreFile = '') then - DataBase.Init ('Ultrastar.db') - else - DataBase.Init (Params.ScoreFile); - - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading DataBase System', 1); - - // Playlist Manager - Log.BenchmarkStart(1); - Log.LogStatus('Playlist Manager', 'Initialization'); - PlaylistMan := TPlaylistManager.Create; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Playlist Manager', 1); - - // GoldenStarsTwinkleMod - Log.BenchmarkStart(1); - Log.LogStatus('Effect Manager', 'Initialization'); - GoldenRec := TEffectManager.Create; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Loading Particel System', 1); - - // Joypad - if (Ini.Joypad = 1) OR (Params.Joypad) then - begin - Log.BenchmarkStart(1); - Log.LogStatus('Initialize Joystick', 'Initialization'); - Joy := TJoy.Create; - Log.BenchmarkEnd(1); - Log.LogBenchmark('Initializing Joystick', 1); - end; - - Log.BenchmarkEnd(0); - Log.LogBenchmark('Loading Time', 0); - - Log.LogError('Creating Core'); - Core := TCore.Create( - USDXShortVersionStr, - MakeVersion(USDX_VERSION_MAJOR, - USDX_VERSION_MINOR, - USDX_VERSION_RELEASE, - chr(0)) - ); - - Log.LogError('Running Core'); - Core.Run; - - //------------------------------ - //Start- Mainloop - //------------------------------ - Log.LogStatus('Main Loop', 'Initialization'); - MainLoop; - - finally - //------------------------------ - //Finish Application - //------------------------------ - - // TODO: - // call an uninitialize routine for every initialize step - // or at least use the corresponding Free-Methods - - UnloadOpenGL; - //TTF_quit(); - SDL_Quit(); - - (* - {$ifdef WIN32} - if assigned(LCD) and (Ini.LPT = 1) then - LCD.Clear; - if assigned(Light) and (Ini.LPT = 2) then - Light.TurnOff; - {$endif} - *) - - if assigned(Log) then - begin - Log.LogStatus('Main Loop', 'Finished'); - Log.Free; - end; - end; -end; - -procedure MainLoop; -var - Delay: integer; -begin - Delay := 0; - SDL_EnableKeyRepeat(125, 125); - - CountSkipTime(); // JB - for some reason this seems to be needed when we use the SDL Timer functions. - while not Done do - begin - // joypad - if (Ini.Joypad = 1) or (Params.Joypad) then - Joy.Update; - - // keyboard events - CheckEvents; - - // display - done := not Display.Draw; - SwapBuffers; - - // light - //Light.Refresh; - - // delay - CountMidTime; - - Delay := Floor(1000 / 100 - 1000 * TimeMid); - - if Delay >= 1 then - SDL_Delay(Delay); // dynamic, maximum is 100 fps - - CountSkipTime; - - // reinitialization of graphics - if Restart then - begin - Reinitialize3D; - Restart := false; - end; - - end; -End; - -procedure CheckEvents; -begin - if Assigned(Display.NextScreen) then - Exit; - - while SDL_PollEvent( @event ) = 1 do - begin - case Event.type_ of - SDL_QUITEV: - begin - Display.Fade := 0; - Display.NextScreenWithCheck := nil; - Display.CheckOK := True; - end; - { - SDL_MOUSEBUTTONDOWN: - with Event.button Do - begin - if State = SDL_BUTTON_LEFT Then - begin - // - end; - end; - } - SDL_VIDEORESIZE: - begin - ScreenW := Event.resize.w; - ScreenH := Event.resize.h; - - screen := SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE); - end; - SDL_KEYDOWN: - begin - // remap the "keypad enter" key to the "standard enter" key - if (Event.key.keysym.sym = SDLK_KP_ENTER) then - Event.key.keysym.sym := SDLK_RETURN; - - if (Event.key.keysym.sym = SDLK_F11) or - ((Event.key.keysym.sym = SDLK_RETURN) and - ((Event.key.keysym.modifier and KMOD_ALT) <> 0)) then // toggle full screen - begin - Ini.FullScreen := integer( not boolean( Ini.FullScreen ) ); - - if boolean( Ini.FullScreen ) then - begin - SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN); - SDL_ShowCursor(0); - end - else - begin - SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE); - SDL_ShowCursor(1); - end; - - glViewPort(0, 0, ScreenW, ScreenH); - end - // ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path - else if (Event.key.keysym.sym = SDLK_SYSREQ) or (Event.key.keysym.sym = SDLK_PRINT) then - Display.ScreenShot - // popup hack... if there is a visible popup then let it handle input instead of underlying screen - // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check) - else if (ScreenPopupError <> nil) and (ScreenPopupError.Visible) then - done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True) - else if (ScreenPopupCheck <> nil) and (ScreenPopupCheck.Visible) then - done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True) - // end of popup hack - else - begin - // check for Screen want to Exit - done := not Display.CurrentScreen^.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True); - - // If Screen wants to Exit - if done then - begin - // If Question Option is enabled then Show Exit Popup - if (Ini.AskbeforeDel = 1) then - begin - Display.CurrentScreen^.CheckFadeTo(nil,'MSG_QUIT_USDX'); - end - else // When asking for exit is disabled then simply exit - begin - Display.Fade := 0; - Display.NextScreenWithCheck := nil; - Display.CheckOK := True; - end; - end; - - end; - end; - { - SDL_JOYAXISMOTION: - begin - beep - end; - } - SDL_JOYBUTTONDOWN: - begin - beep - end; - end; // Case - end; // While -end; - -function GetTimeForBeats(BPM, Beats: real): real; -begin - Result := 60 / BPM * Beats; -end; - -function GetBeats(BPM, msTime: real): real; -begin - Result := BPM * msTime / 60; -end; - -procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real); -var - NewTime: real; -begin - if High(CurrentSong.BPM) = BPMNum then - begin - // last BPM - CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time); - Time := 0; - end - else - begin - // not last BPM - // count how much time is it for start of the new BPM and store it in NewTime - NewTime := GetTimeForBeats(CurrentSong.BPM[BPMNum].BPM, CurrentSong.BPM[BPMNum+1].StartBeat - CurrentSong.BPM[BPMNum].StartBeat); - - // compare it to remaining time - if (Time - NewTime) > 0 then - begin - // there is still remaining time - CurBeat := CurrentSong.BPM[BPMNum].StartBeat; - Time := Time - NewTime; - end - else - begin - // there is no remaining time - CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time); - Time := 0; - end; // if - end; // if -end; - -function GetMidBeat(Time: real): real; -var - CurBeat: real; - CurBPM: integer; -// TopBeat: real; -// TempBeat: real; -// TempTime: real; -begin - Result := 0; - if Length(CurrentSong.BPM) = 1 then - Result := Time * CurrentSong.BPM[0].BPM / 60; - - (* 2 BPMs *) -{ if Length(CurrentSong.BPM) > 1 then begin - (* new system *) - CurBeat := 0; - TopBeat := GetBeats(CurrentSong.BPM[0].BPM, Time); - if TopBeat > CurrentSong.BPM[1].StartBeat then begin - // analyze second BPM - Time := Time - GetTimeForBeats(CurrentSong.BPM[0].BPM, CurrentSong.BPM[1].StartBeat - CurBeat); - CurBeat := CurrentSong.BPM[1].StartBeat; - TopBeat := GetBeats(CurrentSong.BPM[1].BPM, Time); - Result := CurBeat + TopBeat; - - end - else - begin - (* pierwszy przedzial *) - Result := TopBeat; - end; - end;} - - (* more BPMs *) - if Length(CurrentSong.BPM) > 1 then - begin - CurBeat := 0; - CurBPM := 0; - while (Time > 0) do - begin - GetMidBeatSub(CurBPM, Time, CurBeat); - Inc(CurBPM); - end; - - Result := CurBeat; - end; -end; - -function GetTimeFromBeat(Beat: integer): real; -var - CurBPM: integer; -begin - Result := 0; - if Length(CurrentSong.BPM) = 1 then - Result := CurrentSong.GAP / 1000 + Beat * 60 / CurrentSong.BPM[0].BPM; - - (* more BPMs *) - if Length(CurrentSong.BPM) > 1 then - begin - Result := CurrentSong.GAP / 1000; - CurBPM := 0; - while (CurBPM <= High(CurrentSong.BPM)) and - (Beat > CurrentSong.BPM[CurBPM].StartBeat) do - begin - if (CurBPM < High(CurrentSong.BPM)) and - (Beat >= CurrentSong.BPM[CurBPM+1].StartBeat) then - begin - // full range - Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) * - (CurrentSong.BPM[CurBPM+1].StartBeat - CurrentSong.BPM[CurBPM].StartBeat); - end; - - if (CurBPM = High(CurrentSong.BPM)) or - (Beat < CurrentSong.BPM[CurBPM+1].StartBeat) then - begin - // in the middle - Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) * - (Beat - CurrentSong.BPM[CurBPM].StartBeat); - end; - Inc(CurBPM); - end; - - { - while (Time > 0) do - begin - GetMidBeatSub(CurBPM, Time, CurBeat); - Inc(CurBPM); - end; - } - end; // if} -end; - -procedure Sing(Sender: TScreenSing); -var - Count: integer; - CountGr: integer; - CP: integer; - Done: real; - N: integer; -begin - LineState.CurrentTime := LineState.CurrentTime + TimeSkip; - - LineState.OldBeat := LineState.CurrentBeat; - LineState.MidBeat := GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function - LineState.CurrentBeat := Floor(LineState.MidBeat); - -// LineState.OldHalf := LineState.AktHalf; -// LineState.MidHalf := LineState.MidBeat + 0.5; -// LineState.AktHalf := Floor(LineState.MidHalf); - - LineState.OldBeatC := LineState.CurrentBeatC; - LineState.MidBeatC := GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap) / 1000); - LineState.CurrentBeatC := Floor(LineState.MidBeatC); - - LineState.OldBeatD := LineState.CurrentBeatD; - LineState.MidBeatD := -0.5+GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP - LineState.CurrentBeatD := Floor(LineState.MidBeatD); - LineState.FracBeatD := Frac(LineState.MidBeatD); - - // sentences routines - for CountGr := 0 to 0 do //High(Gracz) - begin; - CP := CountGr; - // ustawianie starej parts - LineState.OldLine := Lines[CP].Current; - - // wybieranie aktualnej parts - for Count := 0 to Lines[CP].High do - begin - if LineState.CurrentBeat >= Lines[CP].Line[Count].Start then - Lines[CP].Current := Count; - end; - - // czysczenie nut gracza, gdy to jest nowa plansza - // (optymizacja raz na halfbeat jest zla) - if Lines[CP].Current <> LineState.OldLine then - NewSentence(Sender); - - end; // for CountGr - - // wykonuje operacje raz na beat - if (LineState.CurrentBeat >= 0) and (LineState.OldBeat <> LineState.CurrentBeat) then - NewBeat(Sender); - - // make some operations on clicks - if {(LineState.CurrentBeatC >= 0) and }(LineState.OldBeatC <> LineState.CurrentBeatC) then - NewBeatC(Sender); - - // make some operations when detecting new voice pitch - if (LineState.CurrentBeatD >= 0) and (LineState.OldBeatD <> LineState.CurrentBeatD) then - NewBeatD(Sender); - - // wykonuje operacje w polowie beatu -// if (LineState.AktHalf >= 1) and (LineState.OldHalf <> LineState.AktHalf) then -// NewHalf; - - // plynnie przesuwa text - Done := 1; - for N := 0 to Lines[0].Line[Lines[0].Current].HighNote do - begin - if (Lines[0].Line[Lines[0].Current].Note[N].Start <= LineState.MidBeat) and - (Lines[0].Line[Lines[0].Current].Note[N].Start + Lines[0].Line[Lines[0].Current].Note[N].Length >= LineState.MidBeat) then - begin - Done := (LineState.MidBeat - Lines[0].Line[Lines[0].Current].Note[N].Start) / (Lines[0].Line[Lines[0].Current].Note[N].Length); - end; - end; - - N := Lines[0].Line[Lines[0].Current].HighNote; - - // wylacza ostatnia nute po przejsciu - {// todo: Lyrics - if (Ini.LyricsEffect = 1) and (Done = 1) and - (LineState.MidBeat > Lines[0].Line[Lines[0].Current].Note[N].Start + Lines[0].Line[Lines[0].Current].Note[N].Length) - then Sender.LyricMain.Selected := -1; - - if Done > 1 then Done := 1; - Sender.LyricMain.Done := Done; } - - // use Done with LCD -{ with ScreenSing do begin - if LyricMain.Selected >= 0 then begin - LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done)); - LCD.ShowCursor; - end; - end;} - - -end; - -procedure NewSentence(Sender: TScreenSing); -var -G: Integer; -begin - // czyszczenie nut graczy - for G := 0 to High(Player) do - begin - Player[G].IlNut := 0; - Player[G].HighNote := -1; - SetLength(Player[G].Note, 0); - end; - - // Add Words to Lyrics - with Sender do - begin - {LyricMain.AddCzesc(Lines[0].Current); - if Lines[0].Current < Lines[0].High then - LyricSub.AddCzesc(Lines[0].Current+1) - else - LyricSub.Clear;} - while (not Lyrics.LineinQueue) and (Lyrics.LineCounter <= High(Lines[0].Line)) do - Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]); - end; - - //Sender.UpdateLCD; - - //On Sentence Change... - Sender.onSentenceChange(Lines[0].Current); -end; - -procedure NewBeat(Sender: TScreenSing); -var - Count: integer; -// TempBeat: integer; -begin - // ustawia zaznaczenie tekstu -// SingScreen.LyricMain.Selected := -1; - for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do - if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LineState.CurrentBeat) then - begin - // operates on currently beated note - //Todo: Lyrics - //Sender.LyricMain.Selected := Count; - -// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter); -// LCD.ShowCursor; - - //LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter); - //LCD.ShowCursor; - end; -end; - -procedure NewBeatC; -var - Count: integer; -// LPT_1: integer; -// LPT_2: integer; -begin -// LPT_1 := 1; -// LPT_2 := 1; - - // beat click - if (Ini.BeatClick = 1) and ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0) then - AudioPlayback.PlaySound(SoundLib.Click); - - // debug system on LPT - if ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0) then - begin - //LPT_1 := 0; -// Light.LightOne(0, 150); - - (* - Light.LightOne(1, 200); // beat light - if ParamStr(1) = '-doublelights' then - Light.LightOne(0, 200); // beat light - *) - - -{ if ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod (Lines[0].Resolution * 2) = 0) then - Light.LightOne(0, 150) - else - Light.LightOne(1, 150)} - end; - - for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do - begin - if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LineState.CurrentBeatC) then - begin - // click assist - if Ini.ClickAssist = 1 then - AudioPlayback.PlaySound(SoundLib.Click); - - //LPT_2 := 0; - (* - if ParamStr(1) <> '-doublelights' then - Light.LightOne(0, 150); //125 - *) - - // drum machine - (* - TempBeat := LineState.CurrentBeat;// + 2; - if (TempBeat mod 8 = 0) then Music.PlayDrum; - if (TempBeat mod 8 = 4) then Music.PlayClap; -// if (TempBeat mod 4 = 2) then Music.PlayHihat; - if (TempBeat mod 4 <> 0) then Music.PlayHihat; - *) - end; - end; - - {$IFDEF UseSerialPort} - // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala - {$ENDIF} -end; - -procedure NewBeatD(Sender: TScreenSing); -begin - NewNote(Sender); -end; - -//procedure NewHalf; -//begin -// NewNote; -//end; - -procedure NewNote(Sender: TScreenSing); -var - CP: integer; // current player - S: integer; // sentence - SMin: integer; - SMax: integer; - SDet: integer; // temporary: sentence of detected note - Count: integer; - Mozna: boolean; - New: boolean; - Range: integer; - NoteHit:boolean; -begin -// Log.LogStatus('Beat ' + IntToStr(LineState.CurrentBeat) + ' HalfBeat ' + IntToStr(LineState.AktHalf), 'NewBeat'); -// beep; - - // On linux we get an AV @ NEWNOTE, line 600 of Classes/UMain.pas - if not assigned( AudioInputProcessor.Sound ) then - exit; - - // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth) - // albo juz lepiej nie - for CP := 0 to PlayersPlay-1 do - begin - // analyze buffer - AudioInputProcessor.Sound[CP].AnalyzeBuffer; - - // adds some noise - //LineState.Tone := LineState.Tone + Round(Random(3)) - 1; - - // count min and max sentence range for checking (detection is delayed to the notes we see on the screen) - SMin := Lines[0].Current-1; - if SMin < 0 then - SMin := 0; - SMax := Lines[0].Current; - - // check if we can add new note - Mozna := false; - SDet:=SMin; - for S := SMin to SMax do - begin - for Count := 0 to Lines[0].Line[S].HighNote do - begin - if ((Lines[0].Line[S].Note[Count].Start <= LineState.CurrentBeatD) - and (Lines[0].Line[S].Note[Count].Start + Lines[0].Line[S].Note[Count].Length - 1 >= LineState.CurrentBeatD)) - and (not Lines[0].Line[S].Note[Count].FreeStyle) // but don't allow when it's FreeStyle note - and (Lines[0].Line[S].Note[Count].Length > 0) then // and make sure the note lengths is at least 1 - begin - SDet := S; - Mozna := true; - Break; - end; - end; - end; - - S := SDet; - - //Czas.SzczytJest := true; - //Czas.Tone := 27; - - // gdy moze, to dodaje nute - When Mozna, it adds note (?) - if (AudioInputProcessor.Sound[CP].ToneValid) and (Mozna) then - begin - // operowanie na ostatniej nucie - for Count := 0 to Lines[0].Line[S].HighNote do - begin - if (Lines[0].Line[S].Note[Count].Start <= LineState.OldBeatD+1) and - (Lines[0].Line[S].Note[Count].Start + - Lines[0].Line[S].Note[Count].Length > LineState.OldBeatD+1) then - begin - // to robi, tylko dla pary nut (oryginalnej i gracza) - - // przesuwanie tonu w odpowiednia game - while (AudioInputProcessor.Sound[CP].Tone - Lines[0].Line[S].Note[Count].Tone > 6) do - AudioInputProcessor.Sound[CP].Tone := AudioInputProcessor.Sound[CP].Tone - 12; - - while (AudioInputProcessor.Sound[CP].Tone - Lines[0].Line[S].Note[Count].Tone < -6) do - AudioInputProcessor.Sound[CP].Tone := AudioInputProcessor.Sound[CP].Tone + 12; - - // Half size Notes Patch - NoteHit := false; - - //if Ini.Difficulty = 0 then Range := 2; - //if Ini.Difficulty = 1 then Range := 1; - //if Ini.Difficulty = 2 then Range := 0; - Range := 2 - Ini.Difficulty; - - if abs(Lines[0].Line[S].Note[Count].Tone - AudioInputProcessor.Sound[CP].Tone) <= Range then - begin - AudioInputProcessor.Sound[CP].Tone := Lines[0].Line[S].Note[Count].Tone; - - // Half size Notes Patch - NoteHit := true; - - if (Ini.LineBonus = 0) then - begin - // add points without LineBonus - case Lines[0].Line[S].Note[Count].NoteType of - 1: Player[CP].Score := Player[CP].Score + 10000 / Lines[0].NoteType * - Lines[0].Line[S].Note[Count].NoteType; - 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Lines[0].NoteType * - Lines[0].Line[S].Note[Count].NoteType; - end; - end - else - begin - // add points with Line Bonus - case Lines[0].Line[S].Note[Count].NoteType of - 1: Player[CP].Score := Player[CP].Score + 9000 / Lines[0].NoteType * - Lines[0].Line[S].Note[Count].NoteType; - 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Lines[0].NoteType * - Lines[0].Line[S].Note[Count].NoteType; - end; - end; - - Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10; - Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10; - - Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI; - end; - - end; // operowanie - end; // for - - // sprawdzanie czy to nowa nuta, czy przedluzenie - if S = SMax then - begin - New := true; - // if last has the same tone - if (Player[CP].IlNut > 0 ) and - (Player[CP].Note[Player[CP].HighNote].Tone = AudioInputProcessor.Sound[CP].Tone) and - (Player[CP].Note[Player[CP].HighNote].Start + Player[CP].Note[Player[CP].HighNote].Length = LineState.CurrentBeatD) then - begin - New := false; - end; - - // if is not as new note to control "beacie" (TODO: translate polish "beacie") - for Count := 0 to Lines[0].Line[S].HighNote do - begin - if (Lines[0].Line[S].Note[Count].Start = LineState.CurrentBeatD) then - New := true; - end; - - // dodawanie nowej nuty - if New then - begin - // New Note - Player[CP].IlNut := Player[CP].IlNut + 1; - Player[CP].HighNote := Player[CP].HighNote + 1; - SetLength(Player[CP].Note, Player[CP].IlNut); - Player[CP].Note[Player[CP].HighNote].Start := LineState.CurrentBeatD; - Player[CP].Note[Player[CP].HighNote].Length := 1; - Player[CP].Note[Player[CP].HighNote].Tone := AudioInputProcessor.Sound[CP].Tone; // Ton || TonDokl - Player[CP].Note[Player[CP].HighNote].Detekt := LineState.MidBeat; - - // Half Note Patch - Player[CP].Note[Player[CP].HighNote].Hit := NoteHit; - - //Log.LogStatus('New Note ' + IntToStr(Gracz.Note[Gracz.HighNote].Start), 'NewBeat'); - end - else - begin - // przedluzenie nuty - Player[CP].Note[Player[CP].HighNote].Length := Player[CP].Note[Player[CP].HighNote].Length + 1; - end; - - // check for perfect note and then lit the star (on Draw) - for Count := 0 to Lines[0].Line[S].HighNote do - begin - if (Lines[0].Line[S].Note[Count].Start = Player[CP].Note[Player[CP].HighNote].Start) and - (Lines[0].Line[S].Note[Count].Length = Player[CP].Note[Player[CP].HighNote].Length) and - (Lines[0].Line[S].Note[Count].Tone = Player[CP].Note[Player[CP].HighNote].Tone) then - begin - Player[CP].Note[Player[CP].HighNote].Perfect := true; - end; - end; - end;// else beep; // if S = SMax - - end; // if moze - end; // for CP - // Log.LogStatus('EndBeat', 'NewBeat'); - - //On Sentence End -> For LineBonus + SingBar - if (sDet >= low(Lines[0].Line)) and (sDet <= high(Lines[0].Line)) then - begin - if assigned( Sender ) and - ((Lines[0].Line[SDet].Note[Lines[0].Line[SDet].HighNote].Start + Lines[0].Line[SDet].Note[Lines[0].Line[SDet].HighNote].Length - 1) = LineState.CurrentBeatD) then - begin - Sender.onSentenceEnd(sDet); - end; - end; - -end; - -procedure ClearScores(PlayerNum: integer); -begin - Player[PlayerNum].Score := 0; - Player[PlayerNum].ScoreI := 0; - Player[PlayerNum].ScoreLine := 0; - Player[PlayerNum].ScoreLineI := 0; - Player[PlayerNum].ScoreGolden := 0; - Player[PlayerNum].ScoreGoldenI := 0; - Player[PlayerNum].ScoreTotalI := 0; -end; - - -//-------------------- -// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist -//-------------------- -procedure InitializePaths; - - // Initialize a Path Variable - // After Setting Paths, make sure that Paths exist - function initialize_path( out aPathVar : string; const aLocation : string ): boolean; - var - lWriteable: Boolean; - lAttrib : integer; - begin - lWriteable := false; - aPathVar := aLocation; - - // Make sure the directory is needex - ForceDirectories(aPathVar); - - if DirectoryExists(aPathVar) then - begin - lAttrib := fileGetAttr(aPathVar); - - lWriteable := (lAttrib and faDirectory <> 0) and - not (lAttrib and faReadOnly <> 0) - end; - - if not lWriteable then - Log.LogError('Error: Dir ('+ aLocation +') is Readonly'); - - result := lWriteable; - end; - -begin - initialize_path( LogPath , Platform.GetLogPath ); - initialize_path( SoundPath , Platform.GetGameSharedPath + 'Sounds' + PathDelim ); - initialize_path( ThemePath , Platform.GetGameSharedPath + 'Themes' + PathDelim ); - initialize_path( SkinsPath , Platform.GetGameSharedPath + 'Skins' + PathDelim ); - initialize_path( LanguagesPath , Platform.GetGameSharedPath + 'Languages' + PathDelim ); - initialize_path( PluginPath , Platform.GetGameSharedPath + 'Plugins' + PathDelim ); - initialize_path( VisualsPath , Platform.GetGameSharedPath + 'Visuals' + PathDelim ); - - initialize_path( ScreenshotsPath , Platform.GetGameUserPath + 'Screenshots' + PathDelim ); - - // Users Song Path .... - initialize_path( UserSongPath , Platform.GetGameUserPath + 'Songs' + PathDelim ); - initialize_path( UserCoversPath , Platform.GetGameUserPath + 'Covers' + PathDelim ); - initialize_path( UserPlaylistPath , Platform.GetGameUserPath + 'Playlists' + PathDelim ); - - // Shared Song Path .... - initialize_path( SongPath , Platform.GetGameSharedPath + 'Songs' + PathDelim ); - initialize_path( CoversPath , Platform.GetGameSharedPath + 'Covers' + PathDelim ); - initialize_path( PlaylistPath , Platform.GetGameSharedPath + 'Playlists' + PathDelim ); - - DecimalSeparator := '.'; -end; - -end. - +unit UMain; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + SDL, + UGraphic, + UMusic, + URecord, + UTime, + SysUtils, + UDisplay, + UIni, + ULog, + ULyrics, + UScreenSing, + USong, + OpenGL12, + {$IFDEF UseSerialPort} + //zlportio, //you can disable it and all PortWriteB calls + {$ENDIF} + //ULCD, //TODO: maybe LCD Support as Plugin? + //ULight, //TODO: maybe Light Support as Plugin? + UThemes; + +type + TPlayer = record + Name: string; + + // Index in Teaminfo record + TeamID: Byte; + PlayerID: Byte; + + // Scores + Score: real; + ScoreLine: real; + ScoreGolden: real; + + ScoreI: integer; + ScoreLineI: integer; + ScoreGoldenI: integer; + ScoreTotalI: integer; + + // LineBonus Mod + ScoreLast: Real;//Last Line Score + + // PerfectLineTwinkle Mod (effect) + LastSentencePerfect: Boolean; + + //Meter: real; + + HighNote: integer; + IlNut: integer; + Note: array of record + Start: integer; + Length: integer; + Detekt: real; // accurate place, detected in the note + Tone: real; + Perfect: boolean; // true if the note matches the original one, lit the star + + // Half size Notes Patch + Hit: boolean; // true if the note Hits the Line + end; + end; + + +var + // Absolute Paths + GamePath: string; + SoundPath: string; + SongPath: string; + LogPath: string; + ThemePath: string; + SkinsPath: string; + ScreenshotsPath: string; + CoversPath: string; + LanguagesPath: string; + PluginPath: string; + VisualsPath: string; + PlayListPath: string; + + UserSongPath: string = ''; + UserCoversPath: string = ''; + UserPlaylistPath: string = ''; + + OGL: Boolean; + Done: Boolean; + Event: TSDL_event; + FileName: string; + Restart: boolean; + + // player and music info + Player: array of TPlayer; + PlayersPlay: integer; + + CurrentSong : TSong; + +procedure InitializePaths; + +Procedure Main; +procedure MainLoop; +procedure CheckEvents; +procedure Sing(Sender: TScreenSing); +procedure NewSentence(Sender: TScreenSing); +procedure NewBeat(Sender: TScreenSing); // executed when on then new beat +procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click +procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection +//procedure NewHalf; // executed when in the half between beats +procedure NewNote(Sender: TScreenSing); // detect note +function GetMidBeat(Time: real): real; +function GetTimeFromBeat(Beat: integer): real; +procedure ClearScores(PlayerNum: integer); + +implementation + +uses + USongs, + UJoystick, + math, + UCommandLine, + ULanguage, + SDL_ttf, + USkins, + UCovers, + UCatCovers, + UDataBase, + UPlaylist, + UDLLManager, + UParty, + UConfig, + UCore, + UGraphicClasses, + UPluginDefs, + UPlatform; + +procedure Main; +var + WndTitle: string; +begin + try + WndTitle := USDXVersionStr; + + if Platform.TerminateIfAlreadyRunning( {var} WndTitle) then + Exit; + + //------------------------------ + //StartUp - Create Classes and Load Files + //------------------------------ + USTime := TTime.Create; + + // Commandline Parameter Parser + Params := TCMDParams.Create; + + // Log + Benchmark + Log := TLog.Create; + Log.Title := WndTitle; + Log.Enabled := not Params.NoLog; + Log.BenchmarkStart(0); + + // Language + Log.BenchmarkStart(1); + Log.LogStatus('Initialize Paths', 'Initialization'); + InitializePaths; + Log.LogStatus('Load Language', 'Initialization'); + Language := TLanguage.Create; + + // Add Const Values: + Language.AddConst('US_VERSION', USDXVersionStr); + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Language', 1); + + // SDL + Log.BenchmarkStart(1); + Log.LogStatus('Initialize SDL', 'Initialization'); + SDL_Init(SDL_INIT_VIDEO); + Log.BenchmarkEnd(1); + Log.LogBenchmark('Initializing SDL', 1); + + // SDL_ttf + Log.BenchmarkStart(1); + Log.LogStatus('Initialize SDL_ttf', 'Initialization'); + TTF_Init(); + Log.BenchmarkEnd(1); + Log.LogBenchmark('Initializing SDL_ttf', 1); + + // Skin + Log.BenchmarkStart(1); + Log.LogStatus('Loading Skin List', 'Initialization'); + Skin := TSkin.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Skin List', 1); + + // Ini + Paths + Log.BenchmarkStart(1); + Log.LogStatus('Load Ini', 'Initialization'); + Ini := TIni.Create; + Ini.Load; + + //Load Languagefile + if (Params.Language <> -1) then + Language.ChangeLanguage(ILanguage[Params.Language]) + else + Language.ChangeLanguage(ILanguage[Ini.Language]); + + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Ini', 1); + + // Sound + Log.BenchmarkStart(1); + Log.LogStatus('Initialize Sound', 'Initialization'); + InitializeSound(); + Log.BenchmarkEnd(1); + Log.LogBenchmark('Initializing Sound', 1); + + // Load Sound Settings from Ini + Log.BenchmarkStart(1); + Log.LogStatus('Load Sound Settings', 'Initialization'); + Ini.LoadSoundSettings; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Load Sound Settings', 1); + + // LCD //TODO: maybe LCD Support as Plugin? + //Log.BenchmarkStart(1); + //Log.LogStatus('Load LCD', 'Initialization'); + //LCD := TLCD.Create; + (* + if Ini.LPT = 1 then + begin + //LCD.HalfInterface := true; + LCD.Enable; + LCD.Clear; + LCD.WriteText(1, ' UltraStar '); + LCD.WriteText(2, ' Loading... '); + end; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading LCD', 1); + *) + // Light //TODO: maybe Light Support as Plugin? + (* + Log.BenchmarkStart(1); + Log.LogStatus('Load Light', 'Initialization'); + Light := TLight.Create; + if Ini.LPT = 2 then + begin + Light.Enable; + end; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Light', 1); + *) + + + // Theme + Log.BenchmarkStart(1); + Log.LogStatus('Load Themes', 'Initialization'); + Theme := TTheme.Create(ThemePath + ITheme[Ini.Theme] + '.ini', Ini.Color); + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Themes', 1); + + // Covers Cache + Log.BenchmarkStart(1); + Log.LogStatus('Creating Covers Cache', 'Initialization'); + Covers := TCovers.Create; + Log.LogBenchmark('Loading Covers Cache Array', 1); + Log.BenchmarkStart(1); + + // Category Covers + Log.BenchmarkStart(1); + Log.LogStatus('Creating Category Covers Array', 'Initialization'); + CatCovers:= TCatCovers.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Category Covers Array', 1); + + // Songs + //Log.BenchmarkStart(1); + Log.LogStatus('Creating Song Array', 'Initialization'); + Songs := TSongs.Create; + //Songs.LoadSongList; + + Log.LogStatus('Creating 2nd Song Array', 'Initialization'); + CatSongs := TCatSongs.Create; + + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Songs', 1); + + // PluginManager + Log.BenchmarkStart(1); + Log.LogStatus('PluginManager', 'Initialization'); + DLLMan := TDLLMan.Create; // Load PluginList + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading PluginManager', 1); + + {// Party Mode Manager + Log.BenchmarkStart(1); + Log.LogStatus('PartySession Manager', 'Initialization'); + PartySession := TPartySession.Create; //Load PartySession + + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading PartySession Manager', 1); } + + // Graphics + Log.BenchmarkStart(1); + Log.LogStatus('Initialize 3D', 'Initialization'); + Initialize3D(WndTitle); + Log.BenchmarkEnd(1); + Log.LogBenchmark('Initializing 3D', 1); + + // Score Saving System + Log.BenchmarkStart(1); + Log.LogStatus('DataBase System', 'Initialization'); + DataBase := TDataBaseSystem.Create; + + if (Params.ScoreFile = '') then + DataBase.Init ('Ultrastar.db') + else + DataBase.Init (Params.ScoreFile); + + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading DataBase System', 1); + + // Playlist Manager + Log.BenchmarkStart(1); + Log.LogStatus('Playlist Manager', 'Initialization'); + PlaylistMan := TPlaylistManager.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Playlist Manager', 1); + + // GoldenStarsTwinkleMod + Log.BenchmarkStart(1); + Log.LogStatus('Effect Manager', 'Initialization'); + GoldenRec := TEffectManager.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Particel System', 1); + + // Joypad + if (Ini.Joypad = 1) OR (Params.Joypad) then + begin + Log.BenchmarkStart(1); + Log.LogStatus('Initialize Joystick', 'Initialization'); + Joy := TJoy.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Initializing Joystick', 1); + end; + + Log.BenchmarkEnd(0); + Log.LogBenchmark('Loading Time', 0); + + Log.LogError('Creating Core'); + Core := TCore.Create( + USDXShortVersionStr, + MakeVersion(USDX_VERSION_MAJOR, + USDX_VERSION_MINOR, + USDX_VERSION_RELEASE, + chr(0)) + ); + + Log.LogError('Running Core'); + Core.Run; + + //------------------------------ + //Start- Mainloop + //------------------------------ + Log.LogStatus('Main Loop', 'Initialization'); + MainLoop; + + finally + //------------------------------ + //Finish Application + //------------------------------ + + // TODO: + // call an uninitialize routine for every initialize step + // or at least use the corresponding Free-Methods + + UnloadOpenGL; + //TTF_quit(); + SDL_Quit(); + + (* + {$ifdef WIN32} + if assigned(LCD) and (Ini.LPT = 1) then + LCD.Clear; + if assigned(Light) and (Ini.LPT = 2) then + Light.TurnOff; + {$endif} + *) + + if assigned(Log) then + begin + Log.LogStatus('Main Loop', 'Finished'); + Log.Free; + end; + end; +end; + +procedure MainLoop; +var + Delay: integer; +begin + Delay := 0; + SDL_EnableKeyRepeat(125, 125); + + CountSkipTime(); // JB - for some reason this seems to be needed when we use the SDL Timer functions. + while not Done do + begin + // joypad + if (Ini.Joypad = 1) or (Params.Joypad) then + Joy.Update; + + // keyboard events + CheckEvents; + + // display + done := not Display.Draw; + SwapBuffers; + + // light + //Light.Refresh; + + // delay + CountMidTime; + + Delay := Floor(1000 / 100 - 1000 * TimeMid); + + if Delay >= 1 then + SDL_Delay(Delay); // dynamic, maximum is 100 fps + + CountSkipTime; + + // reinitialization of graphics + if Restart then + begin + Reinitialize3D; + Restart := false; + end; + + end; +End; + +procedure CheckEvents; +begin + if Assigned(Display.NextScreen) then + Exit; + + while SDL_PollEvent( @event ) = 1 do + begin + case Event.type_ of + SDL_QUITEV: + begin + Display.Fade := 0; + Display.NextScreenWithCheck := nil; + Display.CheckOK := True; + end; + { + SDL_MOUSEBUTTONDOWN: + with Event.button Do + begin + if State = SDL_BUTTON_LEFT Then + begin + // + end; + end; + } + SDL_VIDEORESIZE: + begin + ScreenW := Event.resize.w; + ScreenH := Event.resize.h; + + screen := SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE); + end; + SDL_KEYDOWN: + begin + // remap the "keypad enter" key to the "standard enter" key + if (Event.key.keysym.sym = SDLK_KP_ENTER) then + Event.key.keysym.sym := SDLK_RETURN; + + if (Event.key.keysym.sym = SDLK_F11) or + ((Event.key.keysym.sym = SDLK_RETURN) and + ((Event.key.keysym.modifier and KMOD_ALT) <> 0)) then // toggle full screen + begin + Ini.FullScreen := integer( not boolean( Ini.FullScreen ) ); + + if boolean( Ini.FullScreen ) then + begin + SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN); + SDL_ShowCursor(0); + end + else + begin + SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE); + SDL_ShowCursor(1); + end; + + glViewPort(0, 0, ScreenW, ScreenH); + end + // ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path + else if (Event.key.keysym.sym = SDLK_SYSREQ) or (Event.key.keysym.sym = SDLK_PRINT) then + Display.ScreenShot + // popup hack... if there is a visible popup then let it handle input instead of underlying screen + // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check) + else if (ScreenPopupError <> nil) and (ScreenPopupError.Visible) then + done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True) + else if (ScreenPopupCheck <> nil) and (ScreenPopupCheck.Visible) then + done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True) + // end of popup hack + else + begin + // check for Screen want to Exit + done := not Display.CurrentScreen^.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True); + + // If Screen wants to Exit + if done then + begin + // If Question Option is enabled then Show Exit Popup + if (Ini.AskbeforeDel = 1) then + begin + Display.CurrentScreen^.CheckFadeTo(nil,'MSG_QUIT_USDX'); + end + else // When asking for exit is disabled then simply exit + begin + Display.Fade := 0; + Display.NextScreenWithCheck := nil; + Display.CheckOK := True; + end; + end; + + end; + end; + { + SDL_JOYAXISMOTION: + begin + beep + end; + } + SDL_JOYBUTTONDOWN: + begin + beep + end; + end; // Case + end; // While +end; + +function GetTimeForBeats(BPM, Beats: real): real; +begin + Result := 60 / BPM * Beats; +end; + +function GetBeats(BPM, msTime: real): real; +begin + Result := BPM * msTime / 60; +end; + +procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real); +var + NewTime: real; +begin + if High(CurrentSong.BPM) = BPMNum then + begin + // last BPM + CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time); + Time := 0; + end + else + begin + // not last BPM + // count how much time is it for start of the new BPM and store it in NewTime + NewTime := GetTimeForBeats(CurrentSong.BPM[BPMNum].BPM, CurrentSong.BPM[BPMNum+1].StartBeat - CurrentSong.BPM[BPMNum].StartBeat); + + // compare it to remaining time + if (Time - NewTime) > 0 then + begin + // there is still remaining time + CurBeat := CurrentSong.BPM[BPMNum].StartBeat; + Time := Time - NewTime; + end + else + begin + // there is no remaining time + CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time); + Time := 0; + end; // if + end; // if +end; + +function GetMidBeat(Time: real): real; +var + CurBeat: real; + CurBPM: integer; +// TopBeat: real; +// TempBeat: real; +// TempTime: real; +begin + Result := 0; + if Length(CurrentSong.BPM) = 1 then + Result := Time * CurrentSong.BPM[0].BPM / 60; + + (* 2 BPMs *) +{ if Length(CurrentSong.BPM) > 1 then begin + (* new system *) + CurBeat := 0; + TopBeat := GetBeats(CurrentSong.BPM[0].BPM, Time); + if TopBeat > CurrentSong.BPM[1].StartBeat then begin + // analyze second BPM + Time := Time - GetTimeForBeats(CurrentSong.BPM[0].BPM, CurrentSong.BPM[1].StartBeat - CurBeat); + CurBeat := CurrentSong.BPM[1].StartBeat; + TopBeat := GetBeats(CurrentSong.BPM[1].BPM, Time); + Result := CurBeat + TopBeat; + + end + else + begin + (* pierwszy przedzial *) + Result := TopBeat; + end; + end;} + + (* more BPMs *) + if Length(CurrentSong.BPM) > 1 then + begin + CurBeat := 0; + CurBPM := 0; + while (Time > 0) do + begin + GetMidBeatSub(CurBPM, Time, CurBeat); + Inc(CurBPM); + end; + + Result := CurBeat; + end; +end; + +function GetTimeFromBeat(Beat: integer): real; +var + CurBPM: integer; +begin + Result := 0; + if Length(CurrentSong.BPM) = 1 then + Result := CurrentSong.GAP / 1000 + Beat * 60 / CurrentSong.BPM[0].BPM; + + (* more BPMs *) + if Length(CurrentSong.BPM) > 1 then + begin + Result := CurrentSong.GAP / 1000; + CurBPM := 0; + while (CurBPM <= High(CurrentSong.BPM)) and + (Beat > CurrentSong.BPM[CurBPM].StartBeat) do + begin + if (CurBPM < High(CurrentSong.BPM)) and + (Beat >= CurrentSong.BPM[CurBPM+1].StartBeat) then + begin + // full range + Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) * + (CurrentSong.BPM[CurBPM+1].StartBeat - CurrentSong.BPM[CurBPM].StartBeat); + end; + + if (CurBPM = High(CurrentSong.BPM)) or + (Beat < CurrentSong.BPM[CurBPM+1].StartBeat) then + begin + // in the middle + Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) * + (Beat - CurrentSong.BPM[CurBPM].StartBeat); + end; + Inc(CurBPM); + end; + + { + while (Time > 0) do + begin + GetMidBeatSub(CurBPM, Time, CurBeat); + Inc(CurBPM); + end; + } + end; // if} +end; + +procedure Sing(Sender: TScreenSing); +var + Count: integer; + CountGr: integer; + CP: integer; + Done: real; + N: integer; +begin + LineState.CurrentTime := LineState.CurrentTime + TimeSkip; + + LineState.OldBeat := LineState.CurrentBeat; + LineState.MidBeat := GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function + LineState.CurrentBeat := Floor(LineState.MidBeat); + +// LineState.OldHalf := LineState.AktHalf; +// LineState.MidHalf := LineState.MidBeat + 0.5; +// LineState.AktHalf := Floor(LineState.MidHalf); + + LineState.OldBeatC := LineState.CurrentBeatC; + LineState.MidBeatC := GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap) / 1000); + LineState.CurrentBeatC := Floor(LineState.MidBeatC); + + LineState.OldBeatD := LineState.CurrentBeatD; + LineState.MidBeatD := -0.5+GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP + LineState.CurrentBeatD := Floor(LineState.MidBeatD); + LineState.FracBeatD := Frac(LineState.MidBeatD); + + // sentences routines + for CountGr := 0 to 0 do //High(Gracz) + begin; + CP := CountGr; + // ustawianie starej parts + LineState.OldLine := Lines[CP].Current; + + // wybieranie aktualnej parts + for Count := 0 to Lines[CP].High do + begin + if LineState.CurrentBeat >= Lines[CP].Line[Count].Start then + Lines[CP].Current := Count; + end; + + // czysczenie nut gracza, gdy to jest nowa plansza + // (optymizacja raz na halfbeat jest zla) + if Lines[CP].Current <> LineState.OldLine then + NewSentence(Sender); + + end; // for CountGr + + // wykonuje operacje raz na beat + if (LineState.CurrentBeat >= 0) and (LineState.OldBeat <> LineState.CurrentBeat) then + NewBeat(Sender); + + // make some operations on clicks + if {(LineState.CurrentBeatC >= 0) and }(LineState.OldBeatC <> LineState.CurrentBeatC) then + NewBeatC(Sender); + + // make some operations when detecting new voice pitch + if (LineState.CurrentBeatD >= 0) and (LineState.OldBeatD <> LineState.CurrentBeatD) then + NewBeatD(Sender); + + // wykonuje operacje w polowie beatu +// if (LineState.AktHalf >= 1) and (LineState.OldHalf <> LineState.AktHalf) then +// NewHalf; + + // plynnie przesuwa text + Done := 1; + for N := 0 to Lines[0].Line[Lines[0].Current].HighNote do + begin + if (Lines[0].Line[Lines[0].Current].Note[N].Start <= LineState.MidBeat) and + (Lines[0].Line[Lines[0].Current].Note[N].Start + Lines[0].Line[Lines[0].Current].Note[N].Length >= LineState.MidBeat) then + begin + Done := (LineState.MidBeat - Lines[0].Line[Lines[0].Current].Note[N].Start) / (Lines[0].Line[Lines[0].Current].Note[N].Length); + end; + end; + + N := Lines[0].Line[Lines[0].Current].HighNote; + + // wylacza ostatnia nute po przejsciu + {// todo: Lyrics + if (Ini.LyricsEffect = 1) and (Done = 1) and + (LineState.MidBeat > Lines[0].Line[Lines[0].Current].Note[N].Start + Lines[0].Line[Lines[0].Current].Note[N].Length) + then Sender.LyricMain.Selected := -1; + + if Done > 1 then Done := 1; + Sender.LyricMain.Done := Done; } + + // use Done with LCD +{ with ScreenSing do begin + if LyricMain.Selected >= 0 then begin + LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done)); + LCD.ShowCursor; + end; + end;} + + +end; + +procedure NewSentence(Sender: TScreenSing); +var +G: Integer; +begin + // czyszczenie nut graczy + for G := 0 to High(Player) do + begin + Player[G].IlNut := 0; + Player[G].HighNote := -1; + SetLength(Player[G].Note, 0); + end; + + // Add Words to Lyrics + with Sender do + begin + {LyricMain.AddCzesc(Lines[0].Current); + if Lines[0].Current < Lines[0].High then + LyricSub.AddCzesc(Lines[0].Current+1) + else + LyricSub.Clear;} + while (not Lyrics.LineinQueue) and (Lyrics.LineCounter <= High(Lines[0].Line)) do + Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]); + end; + + //Sender.UpdateLCD; + + //On Sentence Change... + Sender.onSentenceChange(Lines[0].Current); +end; + +procedure NewBeat(Sender: TScreenSing); +var + Count: integer; +// TempBeat: integer; +begin + // ustawia zaznaczenie tekstu +// SingScreen.LyricMain.Selected := -1; + for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do + if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LineState.CurrentBeat) then + begin + // operates on currently beated note + //Todo: Lyrics + //Sender.LyricMain.Selected := Count; + +// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter); +// LCD.ShowCursor; + + //LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter); + //LCD.ShowCursor; + end; +end; + +procedure NewBeatC; +var + Count: integer; +// LPT_1: integer; +// LPT_2: integer; +begin +// LPT_1 := 1; +// LPT_2 := 1; + + // beat click + if (Ini.BeatClick = 1) and ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0) then + AudioPlayback.PlaySound(SoundLib.Click); + + // debug system on LPT + if ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0) then + begin + //LPT_1 := 0; +// Light.LightOne(0, 150); + + (* + Light.LightOne(1, 200); // beat light + if ParamStr(1) = '-doublelights' then + Light.LightOne(0, 200); // beat light + *) + + +{ if ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod (Lines[0].Resolution * 2) = 0) then + Light.LightOne(0, 150) + else + Light.LightOne(1, 150)} + end; + + for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do + begin + if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LineState.CurrentBeatC) then + begin + // click assist + if Ini.ClickAssist = 1 then + AudioPlayback.PlaySound(SoundLib.Click); + + //LPT_2 := 0; + (* + if ParamStr(1) <> '-doublelights' then + Light.LightOne(0, 150); //125 + *) + + // drum machine + (* + TempBeat := LineState.CurrentBeat;// + 2; + if (TempBeat mod 8 = 0) then Music.PlayDrum; + if (TempBeat mod 8 = 4) then Music.PlayClap; +// if (TempBeat mod 4 = 2) then Music.PlayHihat; + if (TempBeat mod 4 <> 0) then Music.PlayHihat; + *) + end; + end; + + {$IFDEF UseSerialPort} + // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala + {$ENDIF} +end; + +procedure NewBeatD(Sender: TScreenSing); +begin + NewNote(Sender); +end; + +//procedure NewHalf; +//begin +// NewNote; +//end; + +procedure NewNote(Sender: TScreenSing); +var + CP: integer; // current player + S: integer; // sentence + SMin: integer; + SMax: integer; + SDet: integer; // temporary: sentence of detected note + Count: integer; + Mozna: boolean; + New: boolean; + Range: integer; + NoteHit:boolean; +begin +// Log.LogStatus('Beat ' + IntToStr(LineState.CurrentBeat) + ' HalfBeat ' + IntToStr(LineState.AktHalf), 'NewBeat'); +// beep; + + // On linux we get an AV @ NEWNOTE, line 600 of Classes/UMain.pas + if not assigned( AudioInputProcessor.Sound ) then + exit; + + // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth) + // albo juz lepiej nie + for CP := 0 to PlayersPlay-1 do + begin + // analyze buffer + AudioInputProcessor.Sound[CP].AnalyzeBuffer; + + // adds some noise + //LineState.Tone := LineState.Tone + Round(Random(3)) - 1; + + // count min and max sentence range for checking (detection is delayed to the notes we see on the screen) + SMin := Lines[0].Current-1; + if SMin < 0 then + SMin := 0; + SMax := Lines[0].Current; + + // check if we can add new note + Mozna := false; + SDet:=SMin; + for S := SMin to SMax do + begin + for Count := 0 to Lines[0].Line[S].HighNote do + begin + if ((Lines[0].Line[S].Note[Count].Start <= LineState.CurrentBeatD) + and (Lines[0].Line[S].Note[Count].Start + Lines[0].Line[S].Note[Count].Length - 1 >= LineState.CurrentBeatD)) + and (not Lines[0].Line[S].Note[Count].FreeStyle) // but don't allow when it's FreeStyle note + and (Lines[0].Line[S].Note[Count].Length > 0) then // and make sure the note lengths is at least 1 + begin + SDet := S; + Mozna := true; + Break; + end; + end; + end; + + S := SDet; + + //Czas.SzczytJest := true; + //Czas.Tone := 27; + + // gdy moze, to dodaje nute - When Mozna, it adds note (?) + if (AudioInputProcessor.Sound[CP].ToneValid) and (Mozna) then + begin + // operowanie na ostatniej nucie + for Count := 0 to Lines[0].Line[S].HighNote do + begin + if (Lines[0].Line[S].Note[Count].Start <= LineState.OldBeatD+1) and + (Lines[0].Line[S].Note[Count].Start + + Lines[0].Line[S].Note[Count].Length > LineState.OldBeatD+1) then + begin + // to robi, tylko dla pary nut (oryginalnej i gracza) + + // przesuwanie tonu w odpowiednia game + while (AudioInputProcessor.Sound[CP].Tone - Lines[0].Line[S].Note[Count].Tone > 6) do + AudioInputProcessor.Sound[CP].Tone := AudioInputProcessor.Sound[CP].Tone - 12; + + while (AudioInputProcessor.Sound[CP].Tone - Lines[0].Line[S].Note[Count].Tone < -6) do + AudioInputProcessor.Sound[CP].Tone := AudioInputProcessor.Sound[CP].Tone + 12; + + // Half size Notes Patch + NoteHit := false; + + //if Ini.Difficulty = 0 then Range := 2; + //if Ini.Difficulty = 1 then Range := 1; + //if Ini.Difficulty = 2 then Range := 0; + Range := 2 - Ini.Difficulty; + + if abs(Lines[0].Line[S].Note[Count].Tone - AudioInputProcessor.Sound[CP].Tone) <= Range then + begin + AudioInputProcessor.Sound[CP].Tone := Lines[0].Line[S].Note[Count].Tone; + + // Half size Notes Patch + NoteHit := true; + + if (Ini.LineBonus = 0) then + begin + // add points without LineBonus + case Lines[0].Line[S].Note[Count].NoteType of + 1: Player[CP].Score := Player[CP].Score + 10000 / Lines[0].NoteType * + Lines[0].Line[S].Note[Count].NoteType; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Lines[0].NoteType * + Lines[0].Line[S].Note[Count].NoteType; + end; + end + else + begin + // add points with Line Bonus + case Lines[0].Line[S].Note[Count].NoteType of + 1: Player[CP].Score := Player[CP].Score + 9000 / Lines[0].NoteType * + Lines[0].Line[S].Note[Count].NoteType; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Lines[0].NoteType * + Lines[0].Line[S].Note[Count].NoteType; + end; + end; + + Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10; + Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10; + + Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI; + end; + + end; // operowanie + end; // for + + // sprawdzanie czy to nowa nuta, czy przedluzenie + if S = SMax then + begin + New := true; + // if last has the same tone + if (Player[CP].IlNut > 0 ) and + (Player[CP].Note[Player[CP].HighNote].Tone = AudioInputProcessor.Sound[CP].Tone) and + (Player[CP].Note[Player[CP].HighNote].Start + Player[CP].Note[Player[CP].HighNote].Length = LineState.CurrentBeatD) then + begin + New := false; + end; + + // if is not as new note to control "beacie" (TODO: translate polish "beacie") + for Count := 0 to Lines[0].Line[S].HighNote do + begin + if (Lines[0].Line[S].Note[Count].Start = LineState.CurrentBeatD) then + New := true; + end; + + // dodawanie nowej nuty + if New then + begin + // New Note + Player[CP].IlNut := Player[CP].IlNut + 1; + Player[CP].HighNote := Player[CP].HighNote + 1; + SetLength(Player[CP].Note, Player[CP].IlNut); + Player[CP].Note[Player[CP].HighNote].Start := LineState.CurrentBeatD; + Player[CP].Note[Player[CP].HighNote].Length := 1; + Player[CP].Note[Player[CP].HighNote].Tone := AudioInputProcessor.Sound[CP].Tone; // Ton || TonDokl + Player[CP].Note[Player[CP].HighNote].Detekt := LineState.MidBeat; + + // Half Note Patch + Player[CP].Note[Player[CP].HighNote].Hit := NoteHit; + + //Log.LogStatus('New Note ' + IntToStr(Gracz.Note[Gracz.HighNote].Start), 'NewBeat'); + end + else + begin + // przedluzenie nuty + Player[CP].Note[Player[CP].HighNote].Length := Player[CP].Note[Player[CP].HighNote].Length + 1; + end; + + // check for perfect note and then lit the star (on Draw) + for Count := 0 to Lines[0].Line[S].HighNote do + begin + if (Lines[0].Line[S].Note[Count].Start = Player[CP].Note[Player[CP].HighNote].Start) and + (Lines[0].Line[S].Note[Count].Length = Player[CP].Note[Player[CP].HighNote].Length) and + (Lines[0].Line[S].Note[Count].Tone = Player[CP].Note[Player[CP].HighNote].Tone) then + begin + Player[CP].Note[Player[CP].HighNote].Perfect := true; + end; + end; + end;// else beep; // if S = SMax + + end; // if moze + end; // for CP + // Log.LogStatus('EndBeat', 'NewBeat'); + + //On Sentence End -> For LineBonus + SingBar + if (sDet >= low(Lines[0].Line)) and (sDet <= high(Lines[0].Line)) then + begin + if assigned( Sender ) and + ((Lines[0].Line[SDet].Note[Lines[0].Line[SDet].HighNote].Start + Lines[0].Line[SDet].Note[Lines[0].Line[SDet].HighNote].Length - 1) = LineState.CurrentBeatD) then + begin + Sender.onSentenceEnd(sDet); + end; + end; + +end; + +procedure ClearScores(PlayerNum: integer); +begin + Player[PlayerNum].Score := 0; + Player[PlayerNum].ScoreI := 0; + Player[PlayerNum].ScoreLine := 0; + Player[PlayerNum].ScoreLineI := 0; + Player[PlayerNum].ScoreGolden := 0; + Player[PlayerNum].ScoreGoldenI := 0; + Player[PlayerNum].ScoreTotalI := 0; +end; + +//-------------------- +// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist +//-------------------- +procedure InitializePaths; + + // Initialize a Path Variable + // After Setting Paths, make sure that Paths exist + function initialize_path( out aPathVar : string; const aLocation : string ): boolean; + var + lWriteable: Boolean; + lAttrib : integer; + begin + lWriteable := false; + aPathVar := aLocation; + + // Make sure the directory is needex + ForceDirectories(aPathVar); + + if DirectoryExists(aPathVar) then + begin + lAttrib := fileGetAttr(aPathVar); + + lWriteable := (lAttrib and faDirectory <> 0) and + not (lAttrib and faReadOnly <> 0) + end; + + if not lWriteable then + Log.LogError('Error: Dir ('+ aLocation +') is Readonly'); + + result := lWriteable; + end; + +begin + initialize_path( LogPath , Platform.GetLogPath ); + initialize_path( SoundPath , Platform.GetGameSharedPath + 'Sounds' + PathDelim ); + initialize_path( ThemePath , Platform.GetGameSharedPath + 'Themes' + PathDelim ); + initialize_path( SkinsPath , Platform.GetGameSharedPath + 'Skins' + PathDelim ); + initialize_path( LanguagesPath , Platform.GetGameSharedPath + 'Languages' + PathDelim ); + initialize_path( PluginPath , Platform.GetGameSharedPath + 'Plugins' + PathDelim ); + initialize_path( VisualsPath , Platform.GetGameSharedPath + 'Visuals' + PathDelim ); + + initialize_path( ScreenshotsPath , Platform.GetGameUserPath + 'Screenshots' + PathDelim ); + + // Users Song Path .... + initialize_path( UserSongPath , Platform.GetGameUserPath + 'Songs' + PathDelim ); + initialize_path( UserCoversPath , Platform.GetGameUserPath + 'Covers' + PathDelim ); + initialize_path( UserPlaylistPath , Platform.GetGameUserPath + 'Playlists' + PathDelim ); + + // Shared Song Path .... + initialize_path( SongPath , Platform.GetGameSharedPath + 'Songs' + PathDelim ); + initialize_path( CoversPath , Platform.GetGameSharedPath + 'Covers' + PathDelim ); + initialize_path( PlaylistPath , Platform.GetGameSharedPath + 'Playlists' + PathDelim ); + + DecimalSeparator := '.'; +end; + +end. + diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 index dfe66827..3a15da1d 100644 --- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 +++ b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3 @@ -196,6 +196,286 @@ OpenEditors + + Content + + PBXProjectModuleGUID + 2CA608820D9998CC00EBC4A7 + PBXProjectModuleLabel + UAudioPlayback_Bass.pas + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 2CA608830D9998CC00EBC4A7 + PBXProjectModuleLabel + UAudioPlayback_Bass.pas + _historyCapacity + 0 + bookmark + 2CA6088F0D99999100EBC4A7 + history + + 2CA608790D99987900EBC4A7 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {993, 838}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 38 123 993 879 0 0 1680 1028 + + + + Content + + PBXProjectModuleGUID + 2CA608850D9998CC00EBC4A7 + PBXProjectModuleLabel + UAudioCore_Bass.pas + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 2CA608860D9998CC00EBC4A7 + PBXProjectModuleLabel + UAudioCore_Bass.pas + _historyCapacity + 0 + bookmark + 2CA608900D99999100EBC4A7 + history + + 2CA608780D99987200EBC4A7 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {993, 838}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 15 144 993 879 0 0 1680 1028 + + + + Content + + PBXProjectModuleGUID + 2C019A0B0D998D4A00974970 + PBXProjectModuleLabel + UMain.pas + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 2C019A0C0D998D4A00974970 + PBXProjectModuleLabel + UMain.pas + _historyCapacity + 0 + bookmark + 2CA608910D99999100EBC4A7 + history + + 2CA607DD0D998F0B00EBC4A7 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {1052, 646}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 30 341 1052 687 0 0 1680 1028 + + + + Content + + PBXProjectModuleGUID + 2C0199490D9981C000974970 + PBXProjectModuleLabel + UCommon.pas + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 2C01994A0D9981C000974970 + PBXProjectModuleLabel + UCommon.pas + _historyCapacity + 0 + bookmark + 2CA608920D99999100EBC4A7 + history + + 2CA607DF0D998F0B00EBC4A7 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {754, 847}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 38 134 754 888 0 0 1680 1028 + + + + Content + + PBXProjectModuleGUID + 2C0199430D9981C000974970 + PBXProjectModuleLabel + UScreenMain.pas + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 2C0199440D9981C000974970 + PBXProjectModuleLabel + UScreenMain.pas + _historyCapacity + 0 + bookmark + 2CA608930D99999100EBC4A7 + history + + 2C019A190D998D4A00974970 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {754, 847}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 38 135 754 888 0 0 1680 1028 + + + + Content + + PBXProjectModuleGUID + 2C0199930D9984F900974970 + PBXProjectModuleLabel + UltraStarDX.pas + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 2C0199940D9984F900974970 + PBXProjectModuleLabel + UltraStarDX.pas + _historyCapacity + 0 + bookmark + 2CA608940D99999100EBC4A7 + history + + 2C019A1A0D998D4A00974970 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {987, 762}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 311 168 987 803 0 0 1680 1028 + + + + Content + + PBXProjectModuleGUID + 2C01994C0D9981C000974970 + PBXProjectModuleLabel + OpenGL12.pas + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 2C01994D0D9981C000974970 + PBXProjectModuleLabel + OpenGL12.pas + _historyCapacity + 0 + bookmark + 2CA608950D99999100EBC4A7 + history + + 2C019A1B0D998D4A00974970 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {1070, 868}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 1 119 1070 909 0 0 1680 1028 + + Content @@ -214,10 +494,10 @@ _historyCapacity 0 bookmark - 2CE603FF0D7160F300DB0D88 + 2CA608960D99999100EBC4A7 history - 2CE603EC0D71601400DB0D88 + 2C019A1C0D998D4A00974970 SplitCount @@ -254,10 +534,10 @@ _historyCapacity 0 bookmark - 2CE604000D7160F300DB0D88 + 2CA608970D99999100EBC4A7 history - 2CE603E50D715F9B00DB0D88 + 2C019A1D0D998D4A00974970 SplitCount @@ -349,6 +629,7 @@ 2C4D9D980CC9EE0B0031092D DD7C45450A6E72DE003FA52B 2CF5510C0CDA28F000627463 + 1C37FBAC04509CD000000102 1C37FAAC04509CD000000102 PBXSmartGroupTreeModuleOutlineStateSelectionKey @@ -360,7 +641,7 @@ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {266, 694}} + {{0, 105}, {266, 694}} PBXTopSmartGroupGIDs @@ -462,9 +743,9 @@ TableOfContents - 2CE603E80D71601400DB0D88 + 2CA607D80D998F0B00EBC4A7 1CE0B1FE06471DED0097A5F4 - 2CE603E90D71601400DB0D88 + 2CA607D90D998F0B00EBC4A7 1CE0B20306471E060097A5F4 1CE0B20506471E060097A5F4 @@ -596,15 +877,22 @@ 5 WindowOrderList - 2CE603F80D71601400DB0D88 - 2CE603F90D71601400DB0D88 - 2CE603FA0D71601400DB0D88 + 2CA6081C0D9991E800EBC4A7 + 2CA6081D0D9991E800EBC4A7 + 1C530D57069F1CE1000CFCEE 1C78EAAD065D492600B07095 1CD10A99069EF8BA00B06720 2C65660B0CF2236C0041F7DC 2CE603EE0D71601400DB0D88 2CE603EA0D71601400DB0D88 + 2C01994C0D9981C000974970 + 2C0199930D9984F900974970 + 2C0199430D9981C000974970 + 2C0199490D9981C000974970 + 2C019A0B0D998D4A00974970 + 2CA608850D9998CC00EBC4A7 /Users/eddie/Projekte/UltraStarDX/trunk/Game/Code/MacOSX/UltraStarDX.xcodeproj + 2CA608820D9998CC00EBC4A7 WindowString 799 242 817 753 0 0 1680 1028 @@ -623,12 +911,14 @@ Dock + BecomeActive + ContentConfiguration PBXProjectModuleGUID 1CD0528F0623707200166675 PBXProjectModuleLabel - UTexture.pas + UAudioInput_Bass.pas StatusBarVisibility @@ -645,8 +935,6 @@ 546pt - BecomeActive - ContentConfiguration PBXProjectModuleGUID @@ -686,7 +974,7 @@ TableOfContents 2C65660B0CF2236C0041F7DC - 2CE603CB0D715C9200DB0D88 + 2CA607E60D998F0B00EBC4A7 1CD0528F0623707200166675 XCMainBuildResultsModuleGUID @@ -697,7 +985,7 @@ WindowToolGUID 2C65660B0CF2236C0041F7DC WindowToolIsVisible - + FirstTimeWindowDisplayed @@ -806,13 +1094,13 @@ TableOfContents 1CD10A99069EF8BA00B06720 - 2CE603F10D71601400DB0D88 + 2CA607E70D998F0B00EBC4A7 1C162984064C10D400B95A72 - 2CE603F20D71601400DB0D88 - 2CE603F30D71601400DB0D88 - 2CE603F40D71601400DB0D88 - 2CE603F50D71601400DB0D88 - 2CE603F60D71601400DB0D88 + 2CA607E80D998F0B00EBC4A7 + 2CA607E90D998F0B00EBC4A7 + 2CA607EA0D998F0B00EBC4A7 + 2CA607EB0D998F0B00EBC4A7 + 2CA607EC0D998F0B00EBC4A7 ToolbarConfiguration xcode.toolbar.config.debugV3 @@ -839,14 +1127,12 @@ Dock - BecomeActive - ContentConfiguration PBXProjectModuleGUID 1CDD528C0622207200134675 PBXProjectModuleLabel - UAudioPlayback_Bass.pas + <No Editor> StatusBarVisibility @@ -867,6 +1153,8 @@ 502pt + BecomeActive + ContentConfiguration PBXProjectModuleGUID @@ -902,8 +1190,8 @@ TableOfContents 1C530D57069F1CE1000CFCEE - 2CA2E2DE0D491DDF00E7C4DF - 2CA2E2DF0D491DDF00E7C4DF + 2CA607ED0D998F0B00EBC4A7 + 2CA607EE0D998F0B00EBC4A7 1CDD528C0622207200134675 1CD0528E0623707200166675 @@ -912,7 +1200,7 @@ WindowToolGUID 1C530D57069F1CE1000CFCEE WindowToolIsVisible - + FirstTimeWindowDisplayed @@ -933,6 +1221,8 @@ Dock + BecomeActive + ContentConfiguration PBXProjectModuleGUID @@ -968,7 +1258,7 @@ TableOfContents 1C78EAAD065D492600B07095 - 2CE603F70D71601400DB0D88 + 2CA607EF0D998F0B00EBC4A7 1C78EAAC065D492600B07095 ToolbarConfiguration diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser index 8c30a077..e054f93e 100644 --- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser +++ b/Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser @@ -1,5 +1,63 @@ // !$*UTF8*$! { + 2C0199800D99840900974970 /* config-macosx.inc */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {934, 994}}"; + sepNavSelRange = "{540, 0}"; + sepNavVisRange = "{353, 1694}"; + sepNavWindowFrame = "{{15, 88}, {993, 935}}"; + }; + }; + 2C019A190D998D4A00974970 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */; + name = "UScreenMain.pas: 76"; + rLen = 17; + rLoc = 1560; + rType = 0; + vrLen = 1274; + vrLoc = 1037; + }; + 2C019A1A0D998D4A00974970 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */; + name = "UltraStarDX.pas: 3"; + rLen = 0; + rLoc = 72; + rType = 0; + vrLen = 152; + vrLoc = 0; + }; + 2C019A1B0D998D4A00974970 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C4D9E040CC9EF840031092D /* OpenGL12.pas */; + name = "OpenGL12.pas: 4683"; + rLen = 0; + rLoc = 213678; + rType = 0; + vrLen = 6646; + vrLoc = 207819; + }; + 2C019A1C0D998D4A00974970 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */; + name = "UTexture.pas: 344"; + rLen = 0; + rLoc = 10496; + rType = 0; + vrLen = 1662; + vrLoc = 9347; + }; + 2C019A1D0D998D4A00974970 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */; + name = "UPlatformMacOSX.pas: 13"; + rLen = 0; + rLoc = 717; + rType = 0; + vrLen = 1571; + vrLoc = 493; + }; 2C4B70220CF757A400B0F0BD /* Until5000.dpr */ = { uiCtxt = { sepNavIntBoundsRect = "{{0, 0}, {691, 1218}}"; @@ -10,9 +68,9 @@ }; 2C4D9C620CC9EC8C0031092D /* TextGL.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {729, 7728}}"; - sepNavSelRange = "{4228, 11}"; - sepNavVisRange = "{3672, 1043}"; + sepNavIntBoundsRect = "{{0, 0}, {881, 7532}}"; + sepNavSelRange = "{10589, 66}"; + sepNavVisRange = "{10222, 893}"; sepNavVisRect = "{{0, 5908}, {758, 716}}"; sepNavWindowFrame = "{{38, 157}, {797, 845}}"; }; @@ -35,10 +93,11 @@ }; 2C4D9C670CC9EC8C0031092D /* UCommon.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {715, 4228}}"; - sepNavSelRange = "{1581, 322}"; + sepNavIntBoundsRect = "{{0, 0}, {695, 4060}}"; + sepNavSelRange = "{584, 24}"; + sepNavVisRange = "{249, 1447}"; sepNavVisRect = "{{0, 508}, {715, 815}}"; - sepNavWindowFrame = "{{38, 58}, {754, 944}}"; + sepNavWindowFrame = "{{38, 78}, {754, 944}}"; }; }; 2C4D9C680CC9EC8C0031092D /* UCore.pas */ = { @@ -195,9 +254,9 @@ }; 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {842, 15400}}"; - sepNavSelRange = "{9910, 0}"; - sepNavVisRange = "{9538, 599}"; + sepNavIntBoundsRect = "{{0, 0}, {1026, 16268}}"; + sepNavSelRange = "{31433, 0}"; + sepNavVisRange = "{32193, 1839}"; sepNavVisRect = "{{0, 0}, {1013, 614}}"; sepNavWindowFrame = "{{30, 285}, {1052, 743}}"; }; @@ -262,9 +321,9 @@ }; 2C4D9C840CC9EC8C0031092D /* URecord.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {881, 10862}}"; - sepNavSelRange = "{4086, 14}"; - sepNavVisRange = "{3581, 928}"; + sepNavIntBoundsRect = "{{0, 0}, {738, 8372}}"; + sepNavSelRange = "{10657, 20}"; + sepNavVisRange = "{10176, 1198}"; sepNavVisRect = "{{0, 4312}, {758, 716}}"; sepNavWindowFrame = "{{130, 73}, {797, 845}}"; }; @@ -321,9 +380,9 @@ }; 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {854, 16562}}"; + sepNavIntBoundsRect = "{{0, 0}, {858, 16688}}"; sepNavSelRange = "{10496, 0}"; - sepNavVisRange = "{9347, 1705}"; + sepNavVisRange = "{9368, 1825}"; sepNavVisRect = "{{0, 3420}, {737, 826}}"; sepNavWindowFrame = "{{15, 68}, {776, 955}}"; }; @@ -372,9 +431,9 @@ }; 2C4D9DCC0CC9EE6F0031092D /* UDisplay.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {782, 6748}}"; - sepNavSelRange = "{8084, 0}"; - sepNavVisRange = "{551, 818}"; + sepNavIntBoundsRect = "{{0, 0}, {881, 6944}}"; + sepNavSelRange = "{5028, 51}"; + sepNavVisRange = "{4044, 1359}"; sepNavVisRect = "{{0, 4834}, {758, 716}}"; sepNavWindowFrame = "{{38, 157}, {797, 845}}"; }; @@ -390,9 +449,9 @@ }; 2C4D9DCE0CC9EE6F0031092D /* UMenu.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1220, 21770}}"; - sepNavSelRange = "{25533, 1}"; - sepNavVisRange = "{22476, 1170}"; + sepNavIntBoundsRect = "{{0, 0}, {1284, 22162}}"; + sepNavSelRange = "{51782, 0}"; + sepNavVisRange = "{51126, 1038}"; sepNavVisRect = "{{0, 3972}, {749, 470}}"; sepNavWindowFrame = "{{38, 82}, {898, 920}}"; }; @@ -472,9 +531,9 @@ }; 2C4D9E040CC9EF840031092D /* OpenGL12.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1604, 65450}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{207947, 6380}"; + sepNavIntBoundsRect = "{{0, 0}, {1608, 64064}}"; + sepNavSelRange = "{213678, 0}"; + sepNavVisRange = "{207797, 6669}"; sepNavVisRect = "{{0, 64932}, {1031, 840}}"; sepNavWindowFrame = "{{1, 63}, {1070, 965}}"; }; @@ -489,9 +548,9 @@ }; 2C4D9E440CC9F0ED0031092D /* switches.inc */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {686, 980}}"; - sepNavSelRange = "{485, 14}"; - sepNavVisRange = "{0, 1065}"; + sepNavIntBoundsRect = "{{0, 0}, {624, 1918}}"; + sepNavSelRange = "{1326, 0}"; + sepNavVisRange = "{657, 1095}"; sepNavVisRect = "{{0, 7}, {577, 612}}"; sepNavWindowFrame = "{{15, 282}, {616, 741}}"; }; @@ -521,26 +580,145 @@ }; 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {740, 1848}}"; + sepNavIntBoundsRect = "{{0, 0}, {744, 1890}}"; sepNavSelRange = "{717, 0}"; - sepNavVisRange = "{493, 1700}"; + sepNavVisRange = "{410, 1660}"; sepNavVisRect = "{{0, 105}, {737, 827}}"; sepNavWindowFrame = "{{79, 70}, {776, 956}}"; }; }; + 2CA607DD0D998F0B00EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */; + name = "UMain.pas: 120"; + rLen = 0; + rLoc = 2684; + rType = 0; + vrLen = 1123; + vrLoc = 1767; + }; + 2CA607DF0D998F0B00EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C4D9C670CC9EC8C0031092D /* UCommon.pas */; + name = "UCommon.pas: 52"; + rLen = 0; + rLoc = 807; + rType = 0; + vrLen = 1163; + vrLoc = 56; + }; + 2CA608780D99987200EBC4A7 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */; + }; + 2CA608790D99987900EBC4A7 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */; + }; + 2CA6088F0D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */; + name = "UAudioPlayback_Bass.pas: 219"; + rLen = 3; + rLoc = 4658; + rType = 0; + vrLen = 1277; + vrLoc = 4001; + }; + 2CA608900D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */; + name = "UAudioCore_Bass.pas: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1211; + vrLoc = 0; + }; + 2CA608910D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C4D9C7B0CC9EC8C0031092D /* UMain.pas */; + name = "UMain.pas: 1096"; + rLen = 0; + rLoc = 31433; + rType = 0; + vrLen = 1839; + vrLoc = 32193; + }; + 2CA608920D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C4D9C670CC9EC8C0031092D /* UCommon.pas */; + name = "UCommon.pas: 44"; + rLen = 24; + rLoc = 584; + rType = 0; + vrLen = 1447; + vrLoc = 249; + }; + 2CA608930D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */; + name = "UScreenMain.pas: 76"; + rLen = 17; + rLoc = 1560; + rType = 0; + vrLen = 1336; + vrLoc = 1022; + }; + 2CA608940D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = DDC6851B09F57195004E4BFF /* UltraStarDX.pas */; + name = "UltraStarDX.pas: 3"; + rLen = 0; + rLoc = 72; + rType = 0; + vrLen = 152; + vrLoc = 0; + }; + 2CA608950D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C4D9E040CC9EF840031092D /* OpenGL12.pas */; + name = "OpenGL12.pas: 4683"; + rLen = 0; + rLoc = 213678; + rType = 0; + vrLen = 6669; + vrLoc = 207797; + }; + 2CA608960D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */; + name = "UTexture.pas: 344"; + rLen = 0; + rLoc = 10496; + rType = 0; + vrLen = 1825; + vrLoc = 9368; + }; + 2CA608970D99999100EBC4A7 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */; + name = "UPlatformMacOSX.pas: 13"; + rLen = 0; + rLoc = 717; + rType = 0; + vrLen = 1660; + vrLoc = 410; + }; 2CAC2BDD0D3809F500CA518A /* UAudioInput_Bass.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {815, 4018}}"; - sepNavSelRange = "{2733, 0}"; - sepNavVisRange = "{5604, 1832}"; + sepNavIntBoundsRect = "{{0, 0}, {842, 3766}}"; + sepNavSelRange = "{5570, 0}"; + sepNavVisRange = "{5295, 761}"; sepNavWindowFrame = "{{15, 140}, {874, 883}}"; }; }; 2CAC2BDF0D3809F500CA518A /* UAudioPlayback_Bass.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {729, 7224}}"; + sepNavIntBoundsRect = "{{0, 0}, {934, 6104}}"; sepNavSelRange = "{4658, 3}"; - sepNavVisRange = "{4075, 1054}"; + sepNavVisRange = "{4001, 1277}"; + sepNavWindowFrame = "{{38, 67}, {993, 935}}"; }; }; 2CB9E87D0D43B78400214DFA /* USong.pas */ = { @@ -614,36 +792,20 @@ isa = PBXCodeSenseManager; indexTemplatePath = ""; }; - 2CE603E50D715F9B00DB0D88 /* PBXBookmark */ = { - isa = PBXBookmark; - fRef = 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */; - }; - 2CE603EC0D71601400DB0D88 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */; - rLen = 0; - rLoc = 343; - rType = 1; - }; - 2CE603FF0D7160F300DB0D88 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 2C4D9C8B0CC9EC8C0031092D /* UTexture.pas */; - name = "UTexture.pas: 344"; - rLen = 0; - rLoc = 10496; - rType = 0; - vrLen = 1705; - vrLoc = 9347; + 2CE603DD0D715F6700DB0D88 /* UAudioCore_Bass.pas */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {934, 1764}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 1211}"; + sepNavWindowFrame = "{{15, 88}, {993, 935}}"; + }; }; - 2CE604000D7160F300DB0D88 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 2C8937310CE395CE005D8A87 /* UPlatformMacOSX.pas */; - name = "UPlatformMacOSX.pas: 13"; - rLen = 0; - rLoc = 717; - rType = 0; - vrLen = 1700; - vrLoc = 493; + 2CE603E10D715F8600DB0D88 /* UConfig.pas */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {881, 3080}}"; + sepNavSelRange = "{7279, 0}"; + sepNavVisRange = "{6847, 865}"; + }; }; 2CEA2AF00CE3868E0097A5FF /* PseudoThread.pas */ = { uiCtxt = { @@ -730,9 +892,9 @@ }; 2CF54F4A0CDA1B2B00627463 /* UScreenMain.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {695, 3934}}"; - sepNavSelRange = "{5112, 0}"; - sepNavVisRange = "{4442, 1385}"; + sepNavIntBoundsRect = "{{0, 0}, {695, 4326}}"; + sepNavSelRange = "{1560, 17}"; + sepNavVisRange = "{1022, 1336}"; sepNavVisRect = "{{0, 0}, {715, 815}}"; sepNavWindowFrame = "{{38, 79}, {754, 944}}"; }; @@ -859,16 +1021,18 @@ }; 2CF54F5A0CDA1B2B00627463 /* UScreenPopup.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {715, 3472}}"; - sepNavSelRange = "{56, 0}"; + sepNavIntBoundsRect = "{{0, 0}, {729, 3472}}"; + sepNavSelRange = "{1402, 0}"; + sepNavVisRange = "{987, 787}"; sepNavVisRect = "{{0, 0}, {715, 815}}"; sepNavWindowFrame = "{{38, 58}, {754, 944}}"; }; }; 2CF54F5B0CDA1B2B00627463 /* UScreenScore.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1016, 9478}}"; - sepNavSelRange = "{49, 0}"; + sepNavIntBoundsRect = "{{0, 0}, {792, 14714}}"; + sepNavSelRange = "{4909, 0}"; + sepNavVisRange = "{4202, 810}"; sepNavVisRect = "{{0, 0}, {715, 815}}"; sepNavWindowFrame = "{{15, 79}, {754, 944}}"; }; @@ -893,9 +1057,9 @@ }; 2CF54F5E0CDA1B2B00627463 /* UScreenSong.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {842, 31486}}"; - sepNavSelRange = "{54304, 0}"; - sepNavVisRange = "{53982, 735}"; + sepNavIntBoundsRect = "{{0, 0}, {881, 31066}}"; + sepNavSelRange = "{7241, 96}"; + sepNavVisRange = "{6687, 1426}"; sepNavVisRect = "{{0, 11219}, {1277, 312}}"; sepNavWindowFrame = "{{38, 78}, {754, 944}}"; }; @@ -910,32 +1074,36 @@ }; 2CF54F600CDA1B2B00627463 /* UScreenSongMenu.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {968, 8834}}"; - sepNavSelRange = "{52, 0}"; + sepNavIntBoundsRect = "{{0, 0}, {729, 9352}}"; + sepNavSelRange = "{1910, 0}"; + sepNavVisRange = "{1505, 734}"; sepNavVisRect = "{{0, 0}, {715, 815}}"; sepNavWindowFrame = "{{38, 58}, {754, 944}}"; }; }; 2CF54F610CDA1B2B00627463 /* UScreenStatDetail.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {715, 3514}}"; - sepNavSelRange = "{40, 0}"; + sepNavIntBoundsRect = "{{0, 0}, {729, 3724}}"; + sepNavSelRange = "{1078, 0}"; + sepNavVisRange = "{661, 767}"; sepNavVisRect = "{{0, 0}, {715, 815}}"; sepNavWindowFrame = "{{15, 79}, {754, 944}}"; }; }; 2CF54F620CDA1B2B00627463 /* UScreenStatMain.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1277, 3976}}"; - sepNavSelRange = "{4341, 26}"; + sepNavIntBoundsRect = "{{0, 0}, {729, 4326}}"; + sepNavSelRange = "{1057, 0}"; + sepNavVisRange = "{698, 731}"; sepNavVisRect = "{{0, 2749}, {1277, 312}}"; sepNavWindowFrame = "{{38, 58}, {754, 944}}"; }; }; 2CF54F630CDA1B2B00627463 /* UScreenTop5.pas */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {715, 2324}}"; - sepNavSelRange = "{48, 0}"; + sepNavIntBoundsRect = "{{0, 0}, {729, 2492}}"; + sepNavSelRange = "{996, 0}"; + sepNavVisRange = "{458, 883}"; sepNavVisRect = "{{0, 0}, {715, 815}}"; sepNavWindowFrame = "{{15, 79}, {754, 944}}"; }; @@ -1052,8 +1220,6 @@ activeExecutable = 2CDD4B5D0CB9354800549FAC /* UltraStarDX */; activeTarget = DDC688C709F574E9004E4BFF /* UltraStarDX */; addToTargets = ( - DDC688C709F574E9004E4BFF /* UltraStarDX */, - DDC688D409F57523004E4BFF /* Put all program sources also in this target */, ); breakpoints = ( ); @@ -1184,14 +1350,28 @@ PBXFileDataSource_Warnings_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 225532839; - PBXWorkspaceStateSaveDate = 225532839; + PBXPerProjectTemplateStateSaveDate = 228166993; + PBXWorkspaceStateSaveDate = 228166993; }; perUserProjectItems = { - 2CE603E50D715F9B00DB0D88 /* PBXBookmark */ = 2CE603E50D715F9B00DB0D88 /* PBXBookmark */; - 2CE603EC0D71601400DB0D88 /* PBXTextBookmark */ = 2CE603EC0D71601400DB0D88 /* PBXTextBookmark */; - 2CE603FF0D7160F300DB0D88 /* PBXTextBookmark */ = 2CE603FF0D7160F300DB0D88 /* PBXTextBookmark */; - 2CE604000D7160F300DB0D88 /* PBXTextBookmark */ = 2CE604000D7160F300DB0D88 /* PBXTextBookmark */; + 2C019A190D998D4A00974970 /* PBXTextBookmark */ = 2C019A190D998D4A00974970 /* PBXTextBookmark */; + 2C019A1A0D998D4A00974970 /* PBXTextBookmark */ = 2C019A1A0D998D4A00974970 /* PBXTextBookmark */; + 2C019A1B0D998D4A00974970 /* PBXTextBookmark */ = 2C019A1B0D998D4A00974970 /* PBXTextBookmark */; + 2C019A1C0D998D4A00974970 /* PBXTextBookmark */ = 2C019A1C0D998D4A00974970 /* PBXTextBookmark */; + 2C019A1D0D998D4A00974970 /* PBXTextBookmark */ = 2C019A1D0D998D4A00974970 /* PBXTextBookmark */; + 2CA607DD0D998F0B00EBC4A7 /* PBXTextBookmark */ = 2CA607DD0D998F0B00EBC4A7 /* PBXTextBookmark */; + 2CA607DF0D998F0B00EBC4A7 /* PBXTextBookmark */ = 2CA607DF0D998F0B00EBC4A7 /* PBXTextBookmark */; + 2CA608780D99987200EBC4A7 /* PBXBookmark */ = 2CA608780D99987200EBC4A7 /* PBXBookmark */; + 2CA608790D99987900EBC4A7 /* PBXBookmark */ = 2CA608790D99987900EBC4A7 /* PBXBookmark */; + 2CA6088F0D99999100EBC4A7 /* PBXTextBookmark */ = 2CA6088F0D99999100EBC4A7 /* PBXTextBookmark */; + 2CA608900D99999100EBC4A7 /* PBXTextBookmark */ = 2CA608900D99999100EBC4A7 /* PBXTextBookmark */; + 2CA608910D99999100EBC4A7 /* PBXTextBookmark */ = 2CA608910D99999100EBC4A7 /* PBXTextBookmark */; + 2CA608920D99999100EBC4A7 /* PBXTextBookmark */ = 2CA608920D99999100EBC4A7 /* PBXTextBookmark */; + 2CA608930D99999100EBC4A7 /* PBXTextBookmark */ = 2CA608930D99999100EBC4A7 /* PBXTextBookmark */; + 2CA608940D99999100EBC4A7 /* PBXTextBookmark */ = 2CA608940D99999100EBC4A7 /* PBXTextBookmark */; + 2CA608950D99999100EBC4A7 /* PBXTextBookmark */ = 2CA608950D99999100EBC4A7 /* PBXTextBookmark */; + 2CA608960D99999100EBC4A7 /* PBXTextBookmark */ = 2CA608960D99999100EBC4A7 /* PBXTextBookmark */; + 2CA608970D99999100EBC4A7 /* PBXTextBookmark */ = 2CA608970D99999100EBC4A7 /* PBXTextBookmark */; }; sourceControlManager = 2CDD4B690CB9357000549FAC /* Source Control */; userBuildSettings = { diff --git a/Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj b/Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj index 8b1c3a8a..d7902145 100644 --- a/Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj +++ b/Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj @@ -374,6 +374,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 2C0199800D99840900974970 /* config-macosx.inc */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; name = "config-macosx.inc"; path = "../config-macosx.inc"; sourceTree = SOURCE_ROOT; }; 2C4B70220CF757A400B0F0BD /* Until5000.dpr */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Until5000.dpr; path = ../../../Modis/5000Points/Until5000.dpr; sourceTree = SOURCE_ROOT; }; 2C4D9C620CC9EC8C0031092D /* TextGL.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = TextGL.pas; path = ../Classes/TextGL.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; }; 2C4D9C650CC9EC8C0031092D /* UCatCovers.pas */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 2; lastKnownFileType = sourcecode.pascal; name = UCatCovers.pas; path = ../Classes/UCatCovers.pas; sourceTree = SOURCE_ROOT; tabWidth = 2; }; @@ -795,6 +796,7 @@ DDC6851B09F57195004E4BFF /* UltraStarDX.pas */, 2CF551A70CDA356800627463 /* UltraStar.dpr */, 2C4D9E440CC9F0ED0031092D /* switches.inc */, + 2C0199800D99840900974970 /* config-macosx.inc */, ); name = Source; sourceTree = ""; @@ -1460,7 +1462,7 @@ Carbon, ); PREBINDING = NO; - PRODUCT_NAME = UltraStarDX; + PRODUCT_NAME = "UltraStar Deluxe"; WRAPPER_EXTENSION = app; ZERO_LINK = NO; }; diff --git a/Game/Code/MacOSX/Wrapper/OpenGL12.pas b/Game/Code/MacOSX/Wrapper/OpenGL12.pas index 0efff14e..6afa23ab 100755 --- a/Game/Code/MacOSX/Wrapper/OpenGL12.pas +++ b/Game/Code/MacOSX/Wrapper/OpenGL12.pas @@ -4684,6 +4684,7 @@ type // GLU functions function gluBuild2DMipmaps(target: TGLEnum; components, width, height: TGLint; format, atype: TGLEnum; Data: Pointer): TGLint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external glu32; function gluScaleImage(format: TGLEnum; widthin, heightin: TGLint; typein: TGLEnum; datain: Pointer; widthout, heightout: TGLint; typeout: TGLEnum; dataout: Pointer): TGLint; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external glu32; + function gluErrorString(errCode : GLenum) : PChar; {$IFDEF DLL_STDCALL} stdcall; {$ENDIF} {$IFDEF DLL_CDECL} cdecl; {$ENDIF} external glu32; Procedure LoadOpenGL; Procedure UnloadOpenGL; diff --git a/Game/Code/Menu/UMenu.pas b/Game/Code/Menu/UMenu.pas index dcdcf1ca..4fd9262a 100644 --- a/Game/Code/Menu/UMenu.pas +++ b/Game/Code/Menu/UMenu.pas @@ -46,6 +46,7 @@ type //constructor Create(Back: string; W, H: integer); overload; virtual; // W and H are the number of overlaps // interaction + function WideCharUpperCase(const wchar : WideChar) : WideString; procedure AddInteraction(Typ, Num: integer); procedure SetInteraction(Num: integer); property Interaction: integer read SelInteraction write SetInteraction; @@ -1543,6 +1544,16 @@ begin // beep; end; +function TMenu.WideCharUpperCase(const wchar : WideChar) : WideString; +begin + {$IFDEF DARWIN} + // eddie: WideUpperCase crashes on the mac with WideChars. + Result := UpperCase(wchar); + {$ELSE} + Result := WideUpperCase(wchar); + {$ENDIF} +end; + procedure TMenu.onHide; begin // nothing diff --git a/Game/Code/Screens/UScreenEdit.pas b/Game/Code/Screens/UScreenEdit.pas index 4d105e5f..492191ee 100644 --- a/Game/Code/Screens/UScreenEdit.pas +++ b/Game/Code/Screens/UScreenEdit.pas @@ -30,8 +30,8 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; diff --git a/Game/Code/Screens/UScreenEditConvert.pas b/Game/Code/Screens/UScreenEditConvert.pas index d50d546d..a45e8458 100644 --- a/Game/Code/Screens/UScreenEditConvert.pas +++ b/Game/Code/Screens/UScreenEditConvert.pas @@ -109,13 +109,13 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; + begin + Result := false; + Exit; + end; + end; // check special keys case PressedKey of diff --git a/Game/Code/Screens/UScreenEditHeader.pas b/Game/Code/Screens/UScreenEditHeader.pas index 3b29564a..f0e0a7b7 100644 --- a/Game/Code/Screens/UScreenEditHeader.pas +++ b/Game/Code/Screens/UScreenEditHeader.pas @@ -59,8 +59,8 @@ begin Result := true; If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas index c75661fc..1fb7bff8 100644 --- a/Game/Code/Screens/UScreenEditSub.pas +++ b/Game/Code/Screens/UScreenEditSub.pas @@ -119,13 +119,13 @@ begin If (PressedDown) then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - 'S': + begin + Result := false; + Exit; + end; + 'S': begin // Save Song if SDL_ModState = KMOD_LSHIFT then @@ -181,7 +181,7 @@ begin CopySentence(CopySrc, Lines[0].Current); end; end; - 'T': + 'T': begin // Fixes timings between sentences FixTimings; @@ -232,7 +232,7 @@ begin end; Exit; end; - // Golden Note Patch + // Golden Note Patch 'G': begin case Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType of @@ -260,9 +260,9 @@ begin end; // case Exit; end; - end; - - // check special keys + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenLevel.pas b/Game/Code/Screens/UScreenLevel.pas index 144ec697..1ea79e7f 100644 --- a/Game/Code/Screens/UScreenLevel.pas +++ b/Game/Code/Screens/UScreenLevel.pas @@ -30,15 +30,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; - - // check special keys + begin + Result := false; + Exit; + end; + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas index 2d13ac09..108f811c 100644 --- a/Game/Code/Screens/UScreenMain.pas +++ b/Game/Code/Screens/UScreenMain.pas @@ -56,8 +56,7 @@ uses function TScreenMain.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; var -I: Integer; -SDL_ModState: Word; + SDL_ModState: Word; begin Result := true; @@ -74,7 +73,7 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': begin Result := false; diff --git a/Game/Code/Screens/UScreenOptions.pas b/Game/Code/Screens/UScreenOptions.pas index cfb0c977..3f936602 100644 --- a/Game/Code/Screens/UScreenOptions.pas +++ b/Game/Code/Screens/UScreenOptions.pas @@ -29,15 +29,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; - - // check special keys + begin + Result := false; + Exit; + end; + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenOptionsAdvanced.pas b/Game/Code/Screens/UScreenOptionsAdvanced.pas index c23f133c..adf4125d 100644 --- a/Game/Code/Screens/UScreenOptionsAdvanced.pas +++ b/Game/Code/Screens/UScreenOptionsAdvanced.pas @@ -25,15 +25,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; - - // check special keys + begin + Result := false; + Exit; + end; + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenOptionsGame.pas b/Game/Code/Screens/UScreenOptionsGame.pas index 40200c60..428b2ff7 100644 --- a/Game/Code/Screens/UScreenOptionsGame.pas +++ b/Game/Code/Screens/UScreenOptionsGame.pas @@ -27,15 +27,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; - - // check special keys + begin + Result := false; + Exit; + end; + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenOptionsGraphics.pas b/Game/Code/Screens/UScreenOptionsGraphics.pas index 04656e97..0a736a9d 100644 --- a/Game/Code/Screens/UScreenOptionsGraphics.pas +++ b/Game/Code/Screens/UScreenOptionsGraphics.pas @@ -25,8 +25,8 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; diff --git a/Game/Code/Screens/UScreenOptionsLyrics.pas b/Game/Code/Screens/UScreenOptionsLyrics.pas index 50b7d53d..a314f2f3 100644 --- a/Game/Code/Screens/UScreenOptionsLyrics.pas +++ b/Game/Code/Screens/UScreenOptionsLyrics.pas @@ -25,8 +25,8 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; diff --git a/Game/Code/Screens/UScreenOptionsRecord.pas b/Game/Code/Screens/UScreenOptionsRecord.pas index 0ba554c4..6ee200fa 100644 --- a/Game/Code/Screens/UScreenOptionsRecord.pas +++ b/Game/Code/Screens/UScreenOptionsRecord.pas @@ -78,8 +78,8 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; diff --git a/Game/Code/Screens/UScreenOptionsSound.pas b/Game/Code/Screens/UScreenOptionsSound.pas index 70d92fa5..3cbc65a5 100644 --- a/Game/Code/Screens/UScreenOptionsSound.pas +++ b/Game/Code/Screens/UScreenOptionsSound.pas @@ -25,15 +25,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; - - // check special keys + begin + Result := false; + Exit; + end; + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenOptionsThemes.pas b/Game/Code/Screens/UScreenOptionsThemes.pas index c50256a2..743f5fda 100644 --- a/Game/Code/Screens/UScreenOptionsThemes.pas +++ b/Game/Code/Screens/UScreenOptionsThemes.pas @@ -39,15 +39,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; - - // check special keys + begin + Result := false; + Exit; + end; + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenPartyNewRound.pas b/Game/Code/Screens/UScreenPartyNewRound.pas index e7e2c682..057344dc 100644 --- a/Game/Code/Screens/UScreenPartyNewRound.pas +++ b/Game/Code/Screens/UScreenPartyNewRound.pas @@ -92,13 +92,13 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; + begin + Result := false; + Exit; + end; + end; // check special keys case PressedKey of diff --git a/Game/Code/Screens/UScreenPartyOptions.pas b/Game/Code/Screens/UScreenPartyOptions.pas index c0dde4cc..bd05e653 100644 --- a/Game/Code/Screens/UScreenPartyOptions.pas +++ b/Game/Code/Screens/UScreenPartyOptions.pas @@ -57,13 +57,13 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; + begin + Result := false; + Exit; + end; + end; // check special keys case PressedKey of @@ -80,13 +80,13 @@ begin If (Playlist = 2) and (Length(PlaylistMan.Playlists) = 0) then Exit; // Don't start when SinglePlayer Teams but only Multiplayer Plugins available - OnlyMultiPlayer:=true; - for I := 0 to High(DLLMan.Plugins) do begin - OnlyMultiPlayer := (OnlyMultiPlayer AND DLLMan.Plugins[I].TeamModeOnly); - end; - if (OnlyMultiPlayer) AND ((NumPlayer1 = 0) OR (NumPlayer2 = 0) OR ((NumPlayer3 = 0) AND (NumTeams = 1))) then begin - ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_PLUGINS')); - Exit; + OnlyMultiPlayer:=true; + for I := 0 to High(DLLMan.Plugins) do begin + OnlyMultiPlayer := (OnlyMultiPlayer AND DLLMan.Plugins[I].TeamModeOnly); + end; + if (OnlyMultiPlayer) AND ((NumPlayer1 = 0) OR (NumPlayer2 = 0) OR ((NumPlayer3 = 0) AND (NumTeams = 1))) then begin + ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_PLUGINS')); + Exit; end; //Save Difficulty Ini.Difficulty := SelectsS[SelectLevel].SelectedOption; diff --git a/Game/Code/Screens/UScreenPartyScore.pas b/Game/Code/Screens/UScreenPartyScore.pas index 26e53fcf..c1a84ee6 100644 --- a/Game/Code/Screens/UScreenPartyScore.pas +++ b/Game/Code/Screens/UScreenPartyScore.pas @@ -50,15 +50,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; end; end; - - // check special keys + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenPartyWin.pas b/Game/Code/Screens/UScreenPartyWin.pas index 02079b34..002c6f75 100644 --- a/Game/Code/Screens/UScreenPartyWin.pas +++ b/Game/Code/Screens/UScreenPartyWin.pas @@ -43,13 +43,13 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; + begin + Result := false; + Exit; + end; + end; // check special keys case PressedKey of diff --git a/Game/Code/Screens/UScreenPopup.pas b/Game/Code/Screens/UScreenPopup.pas index c4541050..328e9851 100644 --- a/Game/Code/Screens/UScreenPopup.pas +++ b/Game/Code/Screens/UScreenPopup.pas @@ -49,15 +49,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; end; end; - - // check special keys + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenScore.pas b/Game/Code/Screens/UScreenScore.pas index 358c18d8..23ff86a5 100644 --- a/Game/Code/Screens/UScreenScore.pas +++ b/Game/Code/Screens/UScreenScore.pas @@ -150,15 +150,15 @@ begin Result := true; If (PressedDown) Then begin // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; end; end; - - // check special keys + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas index 6d05c145..bc6c0966 100644 --- a/Game/Code/Screens/UScreenSing.pas +++ b/Game/Code/Screens/UScreenSing.pas @@ -135,9 +135,9 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin + begin //When not ask before Exit then Finish now if (Ini.AskbeforeDel <> 1) then Finish @@ -148,7 +148,7 @@ begin Result := false; Exit; end; - 'V': //Show Visualization + 'V': //Show Visualization begin fShowVisualization := not fShowVisualization; @@ -162,12 +162,12 @@ begin Exit; end; - 'P': + 'P': begin Pause; Exit; end; - end; + end; // check special keys case PressedKey of diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas index a1cd8748..a3467bfe 100644 --- a/Game/Code/Screens/UScreenSong.pas +++ b/Game/Code/Screens/UScreenSong.pas @@ -256,9 +256,9 @@ begin //Jump to Artist/Titel if ((SDL_ModState and KMOD_LALT <> 0) AND (Mode = smNormal)) then begin - if (WideUpperCase(CharCode)[1] in ['A'..'Z']) then + if (WideCharUpperCase(CharCode)[1] in ['A'..'Z']) then begin - Letter := WideUpperCase(CharCode)[1]; + Letter := WideCharUpperCase(CharCode)[1]; I2 := Length(CatSongs.Song); //Jump To Titel @@ -310,8 +310,8 @@ begin end; // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; diff --git a/Game/Code/Screens/UScreenSongMenu.pas b/Game/Code/Screens/UScreenSongMenu.pas index 9cbb1be9..edd3fabb 100644 --- a/Game/Code/Screens/UScreenSongMenu.pas +++ b/Game/Code/Screens/UScreenSongMenu.pas @@ -69,10 +69,10 @@ begin Result := true; if (PressedDown) then begin // Key Down - if (CurMenu = SM_Playlist_New) AND (Interaction=0) then + if (CurMenu = SM_Playlist_New) AND (Interaction=0) then begin // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of '0'..'9', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"': begin Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode; @@ -91,13 +91,13 @@ begin end; // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; + begin + Result := false; + Exit; + end; + end; // check special keys case PressedKey of diff --git a/Game/Code/Screens/UScreenStatDetail.pas b/Game/Code/Screens/UScreenStatDetail.pas index 14f4808e..c5c8245f 100644 --- a/Game/Code/Screens/UScreenStatDetail.pas +++ b/Game/Code/Screens/UScreenStatDetail.pas @@ -45,8 +45,8 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of - 'Q': + case WideCharUpperCase(CharCode)[1] of + 'Q': begin Result := false; Exit; diff --git a/Game/Code/Screens/UScreenStatMain.pas b/Game/Code/Screens/UScreenStatMain.pas index 87bd1b5f..fc0a46b8 100644 --- a/Game/Code/Screens/UScreenStatMain.pas +++ b/Game/Code/Screens/UScreenStatMain.pas @@ -53,15 +53,15 @@ begin If (PressedDown) Then begin // Key Down // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; - - // check special keys + begin + Result := false; + Exit; + end; + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : diff --git a/Game/Code/Screens/UScreenTop5.pas b/Game/Code/Screens/UScreenTop5.pas index 8ebb056c..6893391c 100644 --- a/Game/Code/Screens/UScreenTop5.pas +++ b/Game/Code/Screens/UScreenTop5.pas @@ -38,15 +38,15 @@ begin Result := true; If (PressedDown) Then begin // check normal keys - case WideUpperCase(CharCode)[1] of + case WideCharUpperCase(CharCode)[1] of 'Q': - begin - Result := false; - Exit; - end; - end; - - // check special keys + begin + Result := false; + Exit; + end; + end; + + // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE, diff --git a/Game/Code/switches.inc b/Game/Code/switches.inc index 9b31f3af..1a8f26cc 100644 --- a/Game/Code/switches.inc +++ b/Game/Code/switches.inc @@ -1,132 +1,136 @@ -// Comment by eddie: -// The mac port currently also uses the WIN32 define. -// Once I get the beast compiled, linked and running -// I will change this. -// There are some parts where the WIN32 define could not -// be used. I changed the WIN32 to MSWINDOWS. -// So, for Windows-only code use the MSWINDOWS define. - -{$IFDEF FPC} - {$IFDEF DARWIN} - {$H+} - {$R-} - {$DEFINE WIN32} - {$DEFINE TRANSLATE} - {$DEFINE UTF8_FILENAMES} - {$ELSE} - {$DEFINE LAZARUS} - {$IFNDEF LCL} - // LCL should be defined already - {$MESSAGE Warn 'LCL undefined, compile with "fpc -dLCL ..."!'} - {$DEFINE LCL} - {$ENDIF} - {$ENDIF} - - {$DEFINE DLL_CDECL} - {$DEFINE HasInline} - {$UNDEF UseSerialPort} -{$ELSE} - {$DEFINE Delphi} - - // Delphi version numbers (ignore versions released before Delphi 6 as they miss the $IF directive): - // Delphi 6 (VER140), Delphi 7 (VER150), Delphi 8 (VER160) - // Delphi 9/2005 (VER170), Delphi 10/2006 (VER180) - - // the inline-procedure directive was introduced with Delphi 2005 - {$IF not (Defined(VER140) or Defined(VER150) or Defined(VER160))} - {$DEFINE HasInline} - {$IFEND} - - {$DEFINE DLL_STDCALL} - {$UNDEF UseSerialPort} -{$ENDIF} - - -{$IF Defined(win32)} - // include defines but no constants - {$I config-win.inc} - - // audio config - {$DEFINE WinAudioLib_BASS} - {$IFDEF WinAudioLib_BASS} - {$DEFINE UseBASSPlayback} - {$DEFINE UseBASSInput} - {$ELSE} - {$DEFINE UseFFMpegDecoder} - //{$DEFINE UsePortaudioPlayback} - {$DEFINE UseSDLPlayback} - {$DEFINE UsePortaudioInput} - {$DEFINE UsePortmixer} - {$ENDIF} - {$UNDEF WinAudioLib_BASS} - - // video config - {$IFDEF HaveFFMpeg} - {$DEFINE UseFFMpegVideo} - {$IFDEF HaveSWScale} - {$DEFINE UseSWScale} - {$ENDIF} - {$ENDIF} - - // misc defines - - {$IF Defined(HaveProjectM_0_9)} - {$DEFINE UseProjectM_0_9} - {$ELSEIF Defined(HaveProjectM_1_0_PLUS)} - {$DEFINE UseProjectM_1_0_PLUS} - {$IFEND} - - {$IFDEF DEBUG} - {$IFNDEF DARWIN} - {$APPTYPE CONSOLE} - {$ENDIF} - {$ENDIF} - - {$IFDEF MSWINDOWS} - {$DEFINE UseMIDIPort} - {$ENDIF} -{$ELSEIF Defined(Linux)} - // include defines but no constants - {$I config-linux.inc} - - // audio config - {$IFDEF HaveFFMpeg} - {$DEFINE UseFFMpegDecoder} - {$IFDEF HavePortaudio} - //{$DEFINE UsePortaudioPlayback} - {$DEFINE UseSDLPlayback} - {$DEFINE UsePortaudioInput} - {$ENDIF} - {$ENDIF} - - // video config - {$IFDEF HaveFFMpeg} - {$DEFINE UseFFMpegVideo} - {$IFDEF HaveSWScale} - {$DEFINE UseSWScale} - {$ENDIF} - {$ENDIF} - - // misc defines - {$IFDEF HaveProjectM} - // this causes trouble at the moment - //{$DEFINE UseProjectM_0_9} - {$ENDIF} -{$IFEND} - -{$IF Defined(UseFFMpegVideo) or Defined(UseFFMpegDecoder)} - {$DEFINE UseFFMpeg} -{$IFEND} - -{$IF Defined(UseBASSInput) or Defined(UseBASSPlayback)} - {$DEFINE UseBASS} -{$IFEND} - -{$IF Defined(UsePortaudioInput) or Defined(UsePortaudioPlayback)} - {$DEFINE UsePortaudio} -{$IFEND} - -{$IF Defined(UseProjectM_0_9) or Defined(UseProjectM_1_0_PLUS)} - {$DEFINE UseProjectM} -{$IFEND} - +// Comment by eddie: +// The mac port currently also uses the WIN32 define. +// Once I get the beast compiled, linked and running +// I will change this. +// There are some parts where the WIN32 define could not +// be used. I changed the WIN32 to MSWINDOWS. +// So, for Windows-only code use the MSWINDOWS define. + +{$IFDEF FPC} + {$IFDEF DARWIN} + {$H+} + {$R-} + {$DEFINE WIN32} + {$DEFINE TRANSLATE} + {$DEFINE UTF8_FILENAMES} + {$ELSE} + {$DEFINE LAZARUS} + {$IFNDEF LCL} + // LCL should be defined already + {$MESSAGE Warn 'LCL undefined, compile with "fpc -dLCL ..."!'} + {$DEFINE LCL} + {$ENDIF} + {$ENDIF} + + {$DEFINE DLL_CDECL} + {$DEFINE HasInline} + {$UNDEF UseSerialPort} +{$ELSE} + {$DEFINE Delphi} + + // Delphi version numbers (ignore versions released before Delphi 6 as they miss the $IF directive): + // Delphi 6 (VER140), Delphi 7 (VER150), Delphi 8 (VER160) + // Delphi 9/2005 (VER170), Delphi 10/2006 (VER180) + + // the inline-procedure directive was introduced with Delphi 2005 + {$IF not (Defined(VER140) or Defined(VER150) or Defined(VER160))} + {$DEFINE HasInline} + {$IFEND} + + {$DEFINE DLL_STDCALL} + {$UNDEF UseSerialPort} +{$ENDIF} + + +{$IF Defined(win32)} + // include defines but no constants + {$IFDEF DARWIN} + {$I config-macosx.inc} + {$ELSE} + {$I config-win.inc} + {$ENDIF} + + // audio config + {$DEFINE WinAudioLib_BASS} + {$IFDEF WinAudioLib_BASS} + {$DEFINE UseBASSPlayback} + {$DEFINE UseBASSInput} + {$ELSE} + {$DEFINE UseFFMpegDecoder} + //{$DEFINE UsePortaudioPlayback} + {$DEFINE UseSDLPlayback} + {$DEFINE UsePortaudioInput} + {$DEFINE UsePortmixer} + {$ENDIF} + {$UNDEF WinAudioLib_BASS} + + // video config + {$IFDEF HaveFFMpeg} + {$DEFINE UseFFMpegVideo} + {$IFDEF HaveSWScale} + {$DEFINE UseSWScale} + {$ENDIF} + {$ENDIF} + + // misc defines + + {$IF Defined(HaveProjectM_0_9)} + {$DEFINE UseProjectM_0_9} + {$ELSEIF Defined(HaveProjectM_1_0_PLUS)} + {$DEFINE UseProjectM_1_0_PLUS} + {$IFEND} + + {$IFDEF DEBUG} + {$IFNDEF DARWIN} + {$APPTYPE CONSOLE} + {$ENDIF} + {$ENDIF} + + {$IFDEF MSWINDOWS} + {$DEFINE UseMIDIPort} + {$ENDIF} +{$ELSEIF Defined(Linux)} + // include defines but no constants + {$I config-linux.inc} + + // audio config + {$IFDEF HaveFFMpeg} + {$DEFINE UseFFMpegDecoder} + {$IFDEF HavePortaudio} + //{$DEFINE UsePortaudioPlayback} + {$DEFINE UseSDLPlayback} + {$DEFINE UsePortaudioInput} + {$ENDIF} + {$ENDIF} + + // video config + {$IFDEF HaveFFMpeg} + {$DEFINE UseFFMpegVideo} + {$IFDEF HaveSWScale} + {$DEFINE UseSWScale} + {$ENDIF} + {$ENDIF} + + // misc defines + {$IFDEF HaveProjectM} + // this causes trouble at the moment + //{$DEFINE UseProjectM_0_9} + {$ENDIF} +{$IFEND} + +{$IF Defined(UseFFMpegVideo) or Defined(UseFFMpegDecoder)} + {$DEFINE UseFFMpeg} +{$IFEND} + +{$IF Defined(UseBASSInput) or Defined(UseBASSPlayback)} + {$DEFINE UseBASS} +{$IFEND} + +{$IF Defined(UsePortaudioInput) or Defined(UsePortaudioPlayback)} + {$DEFINE UsePortaudio} +{$IFEND} + +{$IF Defined(UseProjectM_0_9) or Defined(UseProjectM_1_0_PLUS)} + {$DEFINE UseProjectM} +{$IFEND} + -- cgit v1.2.3