aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Game/Code/Classes/UAudioInput_Bass.pas542
-rw-r--r--Game/Code/Classes/UCommon.pas574
-rw-r--r--Game/Code/Classes/UConfig.pas2
-rw-r--r--Game/Code/Classes/UMain.pas2329
-rw-r--r--Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.mode1v3346
-rw-r--r--Game/Code/MacOSX/UltraStarDX.xcodeproj/eddie.pbxuser356
-rw-r--r--Game/Code/MacOSX/UltraStarDX.xcodeproj/project.pbxproj4
-rwxr-xr-xGame/Code/MacOSX/Wrapper/OpenGL12.pas1
-rw-r--r--Game/Code/Menu/UMenu.pas11
-rw-r--r--Game/Code/Screens/UScreenEdit.pas4
-rw-r--r--Game/Code/Screens/UScreenEditConvert.pas12
-rw-r--r--Game/Code/Screens/UScreenEditHeader.pas4
-rw-r--r--Game/Code/Screens/UScreenEditSub.pas22
-rw-r--r--Game/Code/Screens/UScreenLevel.pas16
-rw-r--r--Game/Code/Screens/UScreenMain.pas5
-rw-r--r--Game/Code/Screens/UScreenOptions.pas16
-rw-r--r--Game/Code/Screens/UScreenOptionsAdvanced.pas16
-rw-r--r--Game/Code/Screens/UScreenOptionsGame.pas16
-rw-r--r--Game/Code/Screens/UScreenOptionsGraphics.pas4
-rw-r--r--Game/Code/Screens/UScreenOptionsLyrics.pas4
-rw-r--r--Game/Code/Screens/UScreenOptionsRecord.pas4
-rw-r--r--Game/Code/Screens/UScreenOptionsSound.pas16
-rw-r--r--Game/Code/Screens/UScreenOptionsThemes.pas16
-rw-r--r--Game/Code/Screens/UScreenPartyNewRound.pas12
-rw-r--r--Game/Code/Screens/UScreenPartyOptions.pas26
-rw-r--r--Game/Code/Screens/UScreenPartyScore.pas8
-rw-r--r--Game/Code/Screens/UScreenPartyWin.pas12
-rw-r--r--Game/Code/Screens/UScreenPopup.pas8
-rw-r--r--Game/Code/Screens/UScreenScore.pas8
-rw-r--r--Game/Code/Screens/UScreenSing.pas10
-rw-r--r--Game/Code/Screens/UScreenSong.pas8
-rw-r--r--Game/Code/Screens/UScreenSongMenu.pas16
-rw-r--r--Game/Code/Screens/UScreenStatDetail.pas4
-rw-r--r--Game/Code/Screens/UScreenStatMain.pas16
-rw-r--r--Game/Code/Screens/UScreenTop5.pas16
-rw-r--r--Game/Code/switches.inc268
36 files changed, 2619 insertions, 2113 deletions
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
@@ -200,6 +200,286 @@
<key>Content</key>
<dict>
<key>PBXProjectModuleGUID</key>
+ <string>2CA608820D9998CC00EBC4A7</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UAudioPlayback_Bass.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2CA608830D9998CC00EBC4A7</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UAudioPlayback_Bass.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>2CA6088F0D99999100EBC4A7</string>
+ <key>history</key>
+ <array>
+ <string>2CA608790D99987900EBC4A7</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>Geometry</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 20}, {993, 838}}</string>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <false/>
+ <key>RubberWindowFrame</key>
+ <string>38 123 993 879 0 0 1680 1028 </string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Content</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2CA608850D9998CC00EBC4A7</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UAudioCore_Bass.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2CA608860D9998CC00EBC4A7</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UAudioCore_Bass.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>2CA608900D99999100EBC4A7</string>
+ <key>history</key>
+ <array>
+ <string>2CA608780D99987200EBC4A7</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>Geometry</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 20}, {993, 838}}</string>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <false/>
+ <key>RubberWindowFrame</key>
+ <string>15 144 993 879 0 0 1680 1028 </string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Content</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C019A0B0D998D4A00974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UMain.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C019A0C0D998D4A00974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UMain.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>2CA608910D99999100EBC4A7</string>
+ <key>history</key>
+ <array>
+ <string>2CA607DD0D998F0B00EBC4A7</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>Geometry</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 20}, {1052, 646}}</string>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <false/>
+ <key>RubberWindowFrame</key>
+ <string>30 341 1052 687 0 0 1680 1028 </string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Content</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C0199490D9981C000974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UCommon.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C01994A0D9981C000974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UCommon.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>2CA608920D99999100EBC4A7</string>
+ <key>history</key>
+ <array>
+ <string>2CA607DF0D998F0B00EBC4A7</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>Geometry</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 20}, {754, 847}}</string>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <false/>
+ <key>RubberWindowFrame</key>
+ <string>38 134 754 888 0 0 1680 1028 </string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Content</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C0199430D9981C000974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UScreenMain.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C0199440D9981C000974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UScreenMain.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>2CA608930D99999100EBC4A7</string>
+ <key>history</key>
+ <array>
+ <string>2C019A190D998D4A00974970</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>Geometry</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 20}, {754, 847}}</string>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <false/>
+ <key>RubberWindowFrame</key>
+ <string>38 135 754 888 0 0 1680 1028 </string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Content</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C0199930D9984F900974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UltraStarDX.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C0199940D9984F900974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>UltraStarDX.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>2CA608940D99999100EBC4A7</string>
+ <key>history</key>
+ <array>
+ <string>2C019A1A0D998D4A00974970</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>Geometry</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 20}, {987, 762}}</string>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <false/>
+ <key>RubberWindowFrame</key>
+ <string>311 168 987 803 0 0 1680 1028 </string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Content</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C01994C0D9981C000974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>OpenGL12.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>2C01994D0D9981C000974970</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>OpenGL12.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>2CA608950D99999100EBC4A7</string>
+ <key>history</key>
+ <array>
+ <string>2C019A1B0D998D4A00974970</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>Geometry</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 20}, {1070, 868}}</string>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <false/>
+ <key>RubberWindowFrame</key>
+ <string>1 119 1070 909 0 0 1680 1028 </string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Content</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
<string>2CE603EA0D71601400DB0D88</string>
<key>PBXProjectModuleLabel</key>
<string>UTexture.pas</string>
@@ -214,10 +494,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2CE603FF0D7160F300DB0D88</string>
+ <string>2CA608960D99999100EBC4A7</string>
<key>history</key>
<array>
- <string>2CE603EC0D71601400DB0D88</string>
+ <string>2C019A1C0D998D4A00974970</string>
</array>
</dict>
<key>SplitCount</key>
@@ -254,10 +534,10 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>2CE604000D7160F300DB0D88</string>
+ <string>2CA608970D99999100EBC4A7</string>
<key>history</key>
<array>
- <string>2CE603E50D715F9B00DB0D88</string>
+ <string>2C019A1D0D998D4A00974970</string>
</array>
</dict>
<key>SplitCount</key>
@@ -349,6 +629,7 @@
<string>2C4D9D980CC9EE0B0031092D</string>
<string>DD7C45450A6E72DE003FA52B</string>
<string>2CF5510C0CDA28F000627463</string>
+ <string>1C37FBAC04509CD000000102</string>
<string>1C37FAAC04509CD000000102</string>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
@@ -360,7 +641,7 @@
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
- <string>{{0, 0}, {266, 694}}</string>
+ <string>{{0, 105}, {266, 694}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@@ -462,9 +743,9 @@
</array>
<key>TableOfContents</key>
<array>
- <string>2CE603E80D71601400DB0D88</string>
+ <string>2CA607D80D998F0B00EBC4A7</string>
<string>1CE0B1FE06471DED0097A5F4</string>
- <string>2CE603E90D71601400DB0D88</string>
+ <string>2CA607D90D998F0B00EBC4A7</string>
<string>1CE0B20306471E060097A5F4</string>
<string>1CE0B20506471E060097A5F4</string>
</array>
@@ -596,15 +877,22 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
- <string>2CE603F80D71601400DB0D88</string>
- <string>2CE603F90D71601400DB0D88</string>
- <string>2CE603FA0D71601400DB0D88</string>
+ <string>2CA6081C0D9991E800EBC4A7</string>
+ <string>2CA6081D0D9991E800EBC4A7</string>
+ <string>1C530D57069F1CE1000CFCEE</string>
<string>1C78EAAD065D492600B07095</string>
<string>1CD10A99069EF8BA00B06720</string>
<string>2C65660B0CF2236C0041F7DC</string>
<string>2CE603EE0D71601400DB0D88</string>
<string>2CE603EA0D71601400DB0D88</string>
+ <string>2C01994C0D9981C000974970</string>
+ <string>2C0199930D9984F900974970</string>
+ <string>2C0199430D9981C000974970</string>
+ <string>2C0199490D9981C000974970</string>
+ <string>2C019A0B0D998D4A00974970</string>
+ <string>2CA608850D9998CC00EBC4A7</string>
<string>/Users/eddie/Projekte/UltraStarDX/trunk/Game/Code/MacOSX/UltraStarDX.xcodeproj</string>
+ <string>2CA608820D9998CC00EBC4A7</string>
</array>
<key>WindowString</key>
<string>799 242 817 753 0 0 1680 1028 </string>
@@ -623,12 +911,14 @@
<key>Dock</key>
<array>
<dict>
+ <key>BecomeActive</key>
+ <true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CD0528F0623707200166675</string>
<key>PBXProjectModuleLabel</key>
- <string>UTexture.pas</string>
+ <string>UAudioInput_Bass.pas</string>
<key>StatusBarVisibility</key>
<true/>
</dict>
@@ -645,8 +935,6 @@
<string>546pt</string>
</dict>
<dict>
- <key>BecomeActive</key>
- <true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
@@ -686,7 +974,7 @@
<key>TableOfContents</key>
<array>
<string>2C65660B0CF2236C0041F7DC</string>
- <string>2CE603CB0D715C9200DB0D88</string>
+ <string>2CA607E60D998F0B00EBC4A7</string>
<string>1CD0528F0623707200166675</string>
<string>XCMainBuildResultsModuleGUID</string>
</array>
@@ -697,7 +985,7 @@
<key>WindowToolGUID</key>
<string>2C65660B0CF2236C0041F7DC</string>
<key>WindowToolIsVisible</key>
- <true/>
+ <false/>
</dict>
<dict>
<key>FirstTimeWindowDisplayed</key>
@@ -806,13 +1094,13 @@
<key>TableOfContents</key>
<array>
<string>1CD10A99069EF8BA00B06720</string>
- <string>2CE603F10D71601400DB0D88</string>
+ <string>2CA607E70D998F0B00EBC4A7</string>
<string>1C162984064C10D400B95A72</string>
- <string>2CE603F20D71601400DB0D88</string>
- <string>2CE603F30D71601400DB0D88</string>
- <string>2CE603F40D71601400DB0D88</string>
- <string>2CE603F50D71601400DB0D88</string>
- <string>2CE603F60D71601400DB0D88</string>
+ <string>2CA607E80D998F0B00EBC4A7</string>
+ <string>2CA607E90D998F0B00EBC4A7</string>
+ <string>2CA607EA0D998F0B00EBC4A7</string>
+ <string>2CA607EB0D998F0B00EBC4A7</string>
+ <string>2CA607EC0D998F0B00EBC4A7</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string>
@@ -839,14 +1127,12 @@
<key>Dock</key>
<array>
<dict>
- <key>BecomeActive</key>
- <true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>1CDD528C0622207200134675</string>
<key>PBXProjectModuleLabel</key>
- <string>UAudioPlayback_Bass.pas</string>
+ <string>&lt;No Editor&gt;</string>
<key>StatusBarVisibility</key>
<true/>
</dict>
@@ -867,6 +1153,8 @@
<string>502pt</string>
</dict>
<dict>
+ <key>BecomeActive</key>
+ <true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
@@ -902,8 +1190,8 @@
<key>TableOfContents</key>
<array>
<string>1C530D57069F1CE1000CFCEE</string>
- <string>2CA2E2DE0D491DDF00E7C4DF</string>
- <string>2CA2E2DF0D491DDF00E7C4DF</string>
+ <string>2CA607ED0D998F0B00EBC4A7</string>
+ <string>2CA607EE0D998F0B00EBC4A7</string>
<string>1CDD528C0622207200134675</string>
<string>1CD0528E0623707200166675</string>
</array>
@@ -912,7 +1200,7 @@
<key>WindowToolGUID</key>
<string>1C530D57069F1CE1000CFCEE</string>
<key>WindowToolIsVisible</key>
- <true/>
+ <false/>
</dict>
<dict>
<key>FirstTimeWindowDisplayed</key>
@@ -933,6 +1221,8 @@
<key>Dock</key>
<array>
<dict>
+ <key>BecomeActive</key>
+ <true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
@@ -968,7 +1258,7 @@
<key>TableOfContents</key>
<array>
<string>1C78EAAD065D492600B07095</string>
- <string>2CE603F70D71601400DB0D88</string>
+ <string>2CA607EF0D998F0B00EBC4A7</string>
<string>1C78EAAC065D492600B07095</string>
</array>
<key>ToolbarConfiguration</key>
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 = "<group>";
@@ -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}
+